# Numeric constants as strings

11 messages from 2007-02-19 to 2007-02-20. Participants: Andy Parkins, Junio C Hamano, Shawn O. Pearce, Matthieu Moy, Mark Wooding, Jakub Narebski.
Thread: https://gitlist.dev/t/6879

## Andy Parkins, 2007-02-19 09:16

Subject: Numeric constants as strings
Message-ID: <200702190916.35813.andyparkins@gmail.com>
URL: https://gitlist.dev/e/200702190916.35813.andyparkins%40gmail.com

```
Hello,

I'm working on bringing my hash width literals patch up to date now that 1.5.0 
has passed.  It's all been trivial apart from one line:

#define HASH_WIDTH_ASCII 40
-               printf("%-40s %s%s (%d subtrees)\n",
+               printf("%-" HASH_WIDTH_ASCII "s %s%s (%d subtrees)\n",

This compiles, but I suspect that it's not going to do what I want it to do.  
It's something I've never been able to do in C - how does one get quotes 
around a defined value?  I don't really want to resort to

+               printf("%-*s %s%s (%d subtrees)\n", HASH_WIDTH_ASCII,

As that's a runtime change.



Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com

```

## Junio C Hamano, 2007-02-19 09:38

Subject: Re: Numeric constants as strings
Message-ID: <7virdy8p25.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7virdy8p25.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <200702190916.35813.andyparkins@gmail.com>

```
Andy Parkins <andyparkins@gmail.com> writes:

> I'm working on bringing my hash width literals patch up to
> date now that 1.5.0 has passed.  It's all been trivial apart
> from one line:
>
> #define HASH_WIDTH_ASCII 40
> -               printf("%-40s %s%s (%d subtrees)\n",
> +               printf("%-" HASH_WIDTH_ASCII "s %s%s (%d subtrees)\n",
>
> This compiles, but I suspect that it's not going to do what I
> want it to do.

Doesn't writing "foo" "bar" (two string literals next to each other)
tell the compiler to concatenate them?

```

## Junio C Hamano, 2007-02-19 09:49

Subject: Re: Numeric constants as strings
Message-ID: <7vbqjq8ojr.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vbqjq8ojr.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <200702190916.35813.andyparkins@gmail.com>

```
Andy Parkins <andyparkins@gmail.com> writes:

> I'm working on bringing my hash width literals patch up to
> date now that 1.5.0 has passed.

I do not want to risk discouraging public discussion on this
topic, but I am not sure if this is really worth it.

It is not like if/when we find SHA-1 is inadequate we would just
switch to SHA-256 and redefine HASH_BYTES from 20 to 32 and be
done with it.  With the need for backward compatibility, we
would probably end up changing "unsigned char sha1[20]" to
something that allows us to tell which hash function's result we
are talking about, like:

	struct {
	       	enum { SHA_1, SHA_256 } type;
               	union {
                        unsigned char sha1[20];
                        unsigned char sha256[32];
		} u;
	};

```

## Shawn O. Pearce, 2007-02-19 09:49

Subject: Re: Numeric constants as strings
Message-ID: <20070219094955.GE30030@spearce.org>
URL: https://gitlist.dev/e/20070219094955.GE30030%40spearce.org
In-Reply-To: <7virdy8p25.fsf@assigned-by-dhcp.cox.net>

```
Junio C Hamano <junkio@cox.net> wrote:
> Andy Parkins <andyparkins@gmail.com> writes:
> 
> > I'm working on bringing my hash width literals patch up to
> > date now that 1.5.0 has passed.  It's all been trivial apart
> > from one line:
> >
> > #define HASH_WIDTH_ASCII 40
> > -               printf("%-40s %s%s (%d subtrees)\n",
> > +               printf("%-" HASH_WIDTH_ASCII "s %s%s (%d subtrees)\n",
> >
> > This compiles, but I suspect that it's not going to do what I
> > want it to do.
> 
> Doesn't writing "foo" "bar" (two string literals next to each other)
> tell the compiler to concatenate them?

Yes, but here HASH_WIDTH_ASCII is a number...  wtf is the compiler
generating for the following?

  printf("%-" 40 "s %s%s (%d subtrees)\n",

I did not even realize that was legal C...  Now if the 40 was in
quotes (e.g. "40") then the concatenate rule would apply and we
would get a nice argument to printf.

-- 
Shawn.

```

## Matthieu Moy, 2007-02-19 10:01

Subject: Re: Numeric constants as strings
Message-ID: <vpq1wkm31q4.fsf@olympe.imag.fr>
URL: https://gitlist.dev/e/vpq1wkm31q4.fsf%40olympe.imag.fr
In-Reply-To: <20070219094955.GE30030@spearce.org>

```
"Shawn O. Pearce" <spearce@spearce.org> writes:

> I did not even realize that was legal C...  Now if the 40 was in
> quotes (e.g. "40") then the concatenate rule would apply and we
> would get a nice argument to printf.

I suppose the solution is to use #HASH_WIDTH_ASCII to tell the
preprocessor to put the quotes around HASH_WIDTH_ASCII.

-- 
Matthieu

```

## Mark Wooding, 2007-02-19 10:04

Subject: Re: Numeric constants as strings
Message-ID: <slrnetitgs.sbe.mdw@metalzone.distorted.org.uk>
URL: https://gitlist.dev/e/slrnetitgs.sbe.mdw%40metalzone.distorted.org.uk
In-Reply-To: <200702190916.35813.andyparkins@gmail.com>

```
Andy Parkins <andyparkins@gmail.com> wrote:

> I'm working on bringing my hash width literals patch up to date now
> that 1.5.0 has passed.  It's all been trivial apart from one line:
>
> #define HASH_WIDTH_ASCII 40
> -               printf("%-40s %s%s (%d subtrees)\n",
> +               printf("%-" HASH_WIDTH_ASCII "s %s%s (%d subtrees)\n",

The standard two-step goes

#define STRINGIFY(foo) STRINGIFY_REALLY(foo)
#define STRINGIFY_REALLY(foo) #foo

The purpose of STRINGIFY_REALLY is to macro-expand the argument foo.  If
you just invoked STRINGIFY_REALLY

  printf("%-" STRINGIFY_REALLY(HASH_WIDTH_ASCII) "s %s%s (%d subtrees)\n", 

you'd get

  printf("%-HASH_WIDTH_ASCIIs %s%s (%d subtrees)\n", ...

which is not what you wanted.  However,

  printf("%-" STRINGIFY(HASH_WIDTH_ASCII) "s %s%s (%d subtrees)\n", 

will do the right thing.

-- [mdw]

```

## Andy Parkins, 2007-02-19 10:14

Subject: Re: Numeric constants as strings
Message-ID: <200702191014.23055.andyparkins@gmail.com>
URL: https://gitlist.dev/e/200702191014.23055.andyparkins%40gmail.com
In-Reply-To: <7virdy8p25.fsf@assigned-by-dhcp.cox.net>

```
On Monday 2007 February 19 09:38, Junio C Hamano wrote:

> > #define HASH_WIDTH_ASCII 40
> > -               printf("%-40s %s%s (%d subtrees)\n",
> > +               printf("%-" HASH_WIDTH_ASCII "s %s%s (%d subtrees)\n",
> >
> > This compiles, but I suspect that it's not going to do what I
> > want it to do.
>
> Doesn't writing "foo" "bar" (two string literals next to each other)
> tell the compiler to concatenate them?

It's not a string literal though.

It's
 #define HASH_WIDTH_ASCII 40
rather than
 #define HASH_WIDTH_ASCII "40"

I'm wondering how to turn the first into the second using the preprocessor.


Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com

```

## Andy Parkins, 2007-02-19 10:54

Subject: Re: Numeric constants as strings
Message-ID: <200702191055.00203.andyparkins@gmail.com>
URL: https://gitlist.dev/e/200702191055.00203.andyparkins%40gmail.com
In-Reply-To: <vpq1wkm31q4.fsf@olympe.imag.fr>

```
On Monday 2007 February 19 10:01, Matthieu Moy wrote:
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> > I did not even realize that was legal C...  Now if the 40 was in
> > quotes (e.g. "40") then the concatenate rule would apply and we
> > would get a nice argument to printf.
>
> I suppose the solution is to use #HASH_WIDTH_ASCII to tell the
> preprocessor to put the quotes around HASH_WIDTH_ASCII.

I'm afraid that only works when you're token pasting parameters in a #define 
macro.

For example:

 #define macro(x) "foo" #x "baz"

Then, macro(bar) expands to "foo" "bar" "baz".  However, the following does 
not work:

 #define BAR bar
 #define macro "foo" #BAR "baz"
 
This is because BAR is not a macro parameter.  I've also tried it indirectly:

 #define BAR bar
 #define MAKESTRING(x) #x
 #define macro "foo" MAKESTRING(BAR) "baz"

But this expands to "foo" "BAR" "baz".  Also wrong.  Equally, using # anywhere 
but during a #define doesn't work, so I can't simply write

 printf( "%-" #HASH_WIDTH_ASCII "s", string );

Woe is me. :-(


Andy
-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com

```

## Andy Parkins, 2007-02-19 11:00

Subject: Re: Numeric constants as strings
Message-ID: <200702191100.42953.andyparkins@gmail.com>
URL: https://gitlist.dev/e/200702191100.42953.andyparkins%40gmail.com
In-Reply-To: <7vbqjq8ojr.fsf@assigned-by-dhcp.cox.net>

```
On Monday 2007 February 19 09:49, Junio C Hamano wrote:

> I do not want to risk discouraging public discussion on this
> topic, but I am not sure if this is really worth it.

It's not primarily for that purpose, but rather to improve readability.

For example, this little bit of patch:

-       if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
+       if (get_sha1_hex(buffer+5, tree_sha1) || buffer[HASH_WIDTH_ASCII+5] != '\n')
                return objerror(&commit->object, "invalid 'tree' line format - bad sha1");
-       buffer += 46;
+       buffer += HASH_WIDTH_ASCII+6;
        while (!memcmp(buffer, "parent ", 7)) {
-               if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n')
+               if (get_sha1_hex(buffer+7, sha1) || buffer[HASH_WIDTH_ASCII+7] != '\n')
                        return objerror(&commit->object, "invalid 'parent' line format - bad sha1");
-               buffer += 48;
+               buffer += HASH_WIDTH_ASCII+8;

Using HASH_WIDTH_ASCII+8 is much clearer for a reader to be able to understand
intent than 48.  Especially when the variables in question are called "buffer"
it's harder to track what is being stored in the buffer without a named constant.

There are also a few other places where 20 is used and HASH_WIDTH_ASCII is not
intended.



Andy

-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com

```

## Andy Parkins, 2007-02-19 11:02

Subject: Re: Numeric constants as strings
Message-ID: <200702191103.00431.andyparkins@gmail.com>
URL: https://gitlist.dev/e/200702191103.00431.andyparkins%40gmail.com
In-Reply-To: <slrnetitgs.sbe.mdw@metalzone.distorted.org.uk>

```
On Monday 2007 February 19 10:04, Mark Wooding wrote:

> #define STRINGIFY(foo) STRINGIFY_REALLY(foo)
> #define STRINGIFY_REALLY(foo) #foo
>   printf("%-" STRINGIFY(HASH_WIDTH_ASCII) "s %s%s (%d subtrees)\n",

Ah ha!  Magical.  You've taught me something there.  Thanks.


Andy

-- 
Dr Andy Parkins, M Eng (hons), MIEE
andyparkins@gmail.com

```

## Jakub Narebski, 2007-02-20 13:06

Subject: Re: Numeric constants as strings
Message-ID: <ererl9$df0$1@sea.gmane.org>
URL: https://gitlist.dev/e/ererl9%24df0%241%40sea.gmane.org
In-Reply-To: <200702191103.00431.andyparkins@gmail.com>

```
Andy Parkins wrote:

> On Monday 2007 February 19 10:04, Mark Wooding wrote:
> 
>> #define STRINGIFY(foo) STRINGIFY_REALLY(foo)
>> #define STRINGIFY_REALLY(foo) #foo
>>   printf("%-" STRINGIFY(HASH_WIDTH_ASCII) "s %s%s (%d subtrees)\n",
> 
> Ah ha!  Magical.  You've taught me something there.  Thanks.

This trick is in the cpp documentation. 
(cpp.info.gz)Stringification

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

```
