Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #99324 > unrolled thread

Sum using variadic macros

Started byThiago Adams <thiago.adams@gmail.com>
First post2016-12-14 02:54 -0800
Last post2016-12-14 19:40 +0000
Articles 16 — 8 participants

Back to article view | Back to comp.lang.c


Contents

  Sum using variadic macros Thiago Adams <thiago.adams@gmail.com> - 2016-12-14 02:54 -0800
    Re: Sum using variadic macros Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-14 11:51 +0000
      Re: Sum using variadic macros David Brown <david.brown@hesbynett.no> - 2016-12-14 13:58 +0100
        Re: Sum using variadic macros Richard Heathfield <rjh@cpax.org.uk> - 2016-12-14 14:01 +0000
        Re: Sum using variadic macros Thiago Adams <thiago.adams@gmail.com> - 2016-12-14 08:05 -0800
          Re: Sum using variadic macros BartC <bc@freeuk.com> - 2016-12-14 19:20 +0000
            Re: Sum using variadic macros Thiago Adams <thiago.adams@gmail.com> - 2016-12-14 11:26 -0800
              Re: Sum using variadic macros BartC <bc@freeuk.com> - 2016-12-14 20:06 +0000
      Re: Sum using variadic macros Thiago Adams <thiago.adams@gmail.com> - 2016-12-14 05:25 -0800
        Re: Sum using variadic macros mark.bluemel@gmail.com - 2016-12-14 08:10 -0800
          Re: Sum using variadic macros Thiago Adams <thiago.adams@gmail.com> - 2016-12-14 08:23 -0800
            Re: Sum using variadic macros Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-12-14 11:32 -0800
        Re: Sum using variadic macros Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-14 16:26 +0000
          Re: Sum using variadic macros David Brown <david.brown@hesbynett.no> - 2016-12-14 19:09 +0100
            Re: Sum using variadic macros supercat@casperkitty.com - 2016-12-14 11:33 -0800
            Re: Sum using variadic macros Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-14 19:40 +0000

#99324 — Sum using variadic macros

FromThiago Adams <thiago.adams@gmail.com>
Date2016-12-14 02:54 -0800
SubjectSum using variadic macros
Message-ID<03e6722a-248a-46e2-b06d-d1e84e471463@googlegroups.com>
Is it possible to do a sum with variadic macros?

SUM('a', 'b', 'c') 

I want to expand to 'a' + 'b' + 'c'


(I'm not finding good samples on the internet)


--

What I was planning to do is to generate a hash.
HASH('t', 'h', 'i', 's');

Doing some tests I realized that "abc"[0] is not a constant expression in C.

[toc] | [next] | [standalone]


#99329

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-12-14 11:51 +0000
Message-ID<871sxa919h.fsf@bsb.me.uk>
In reply to#99324
Thiago Adams <thiago.adams@gmail.com> writes:

> Is it possible to do a sum with variadic macros?
>
> SUM('a', 'b', 'c') 
>
> I want to expand to 'a' + 'b' + 'c'

If you can accept a maximum number of arguments and the operation has an
identity element you can so this:

#define sum(...) (sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0))
#define sum2(a, b, c, d, e, f, g, h, ...) a + b + c + d + e + f + g + h

<snip>
> What I was planning to do is to generate a hash.
> HASH('t', 'h', 'i', 's');

Maybe.  That depends on the hash computation.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#99334

FromDavid Brown <david.brown@hesbynett.no>
Date2016-12-14 13:58 +0100
Message-ID<o2rfjg$vi$1@dont-email.me>
In reply to#99329
On 14/12/16 12:51, Ben Bacarisse wrote:
> Thiago Adams <thiago.adams@gmail.com> writes:
> 
>> Is it possible to do a sum with variadic macros?
>>
>> SUM('a', 'b', 'c') 
>>
>> I want to expand to 'a' + 'b' + 'c'
> 
> If you can accept a maximum number of arguments and the operation has an
> identity element you can so this:
> 
> #define sum(...) (sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0))
> #define sum2(a, b, c, d, e, f, g, h, ...) a + b + c + d + e + f + g + h
> 
> <snip>
>> What I was planning to do is to generate a hash.
>> HASH('t', 'h', 'i', 's');
> 
> Maybe.  That depends on the hash computation.
> 

For this sort of thing, I usually make a short custom pre-processor.
It's easy to make a little Python script (or whatever language you
prefer) that finds instances of HASH("this") and generates an include
file that defines an enum with constants of the form "hash_this".  Your
C code just includes this generated file, and has a macro definition of
HASH that expands to the enum tag.

At the risk of heresy, constexpr has made this sort of thing vastly
easier in C++.

[toc] | [prev] | [next] | [standalone]


#99339

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-14 14:01 +0000
Message-ID<o2rj8p$e8u$2@dont-email.me>
In reply to#99334
On 14/12/16 12:58, David Brown wrote:

<snip>

> At the risk of heresy, constexpr has made this sort of thing vastly
> easier in C++.

Burn him! Burn him!

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#99345

FromThiago Adams <thiago.adams@gmail.com>
Date2016-12-14 08:05 -0800
Message-ID<e2a70b5a-462d-4510-b994-b2dd4a77c46a@googlegroups.com>
In reply to#99334
On Wednesday, December 14, 2016 at 10:58:50 AM UTC-2, David Brown wrote:
> On 14/12/16 12:51, Ben Bacarisse wrote:
> > Thiago Adams writes:
> > 
> >> Is it possible to do a sum with variadic macros?
> >>
> >> SUM('a', 'b', 'c') 
> >>
> >> I want to expand to 'a' + 'b' + 'c'
> > 
> > If you can accept a maximum number of arguments and the operation has an
> > identity element you can so this:
> > 
> > #define sum(...) (sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0))
> > #define sum2(a, b, c, d, e, f, g, h, ...) a + b + c + d + e + f + g + h
> > 
> > <snip>
> >> What I was planning to do is to generate a hash.
> >> HASH('t', 'h', 'i', 's');
> > 
> > Maybe.  That depends on the hash computation.
> > 
> 
> For this sort of thing, I usually make a short custom pre-processor.
> It's easy to make a little Python script (or whatever language you
> prefer) that finds instances of HASH("this") and generates an include
> file that defines an enum with constants of the form "hash_this".  Your
> C code just includes this generated file, and has a macro definition of
> HASH that expands to the enum tag.
> 
> At the risk of heresy, constexpr has made this sort of thing vastly
> easier in C++.

Yes, I agree.
This is not so important, I can put the computed number instead of the macro.
I would use macro only if it was easy and clear.





[toc] | [prev] | [next] | [standalone]


#99369

FromBartC <bc@freeuk.com>
Date2016-12-14 19:20 +0000
Message-ID<o2s5vd$k2d$1@dont-email.me>
In reply to#99345
On 14/12/2016 16:05, Thiago Adams wrote:
> On Wednesday, December 14, 2016 at 10:58:50 AM UTC-2, David Brown wrote:

>> For this sort of thing, I usually make a short custom pre-processor.
>> It's easy to make a little Python script (or whatever language you
>> prefer) that finds instances of HASH("this") and generates an include
>> file that defines an enum with constants of the form "hash_this".  Your
>> C code just includes this generated file, and has a macro definition of
>> HASH that expands to the enum tag.
>>
>> At the risk of heresy, constexpr has made this sort of thing vastly
>> easier in C++.
>
> Yes, I agree.
> This is not so important, I can put the computed number instead of the macro.
> I would use macro only if it was easy and clear.

Why can't you calculate it at runtime during initialisation? Or does it 
have to be used in array bound or switch-case expressions?

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#99370

FromThiago Adams <thiago.adams@gmail.com>
Date2016-12-14 11:26 -0800
Message-ID<5e39ec50-7c87-4d76-8979-981f0ebdbbf6@googlegroups.com>
In reply to#99369
On Wednesday, December 14, 2016 at 5:20:39 PM UTC-2, Bart wrote:
> On 14/12/2016 16:05, Thiago Adams wrote:
> > On Wednesday, December 14, 2016 at 10:58:50 AM UTC-2, David Brown wrote:
> 
> >> For this sort of thing, I usually make a short custom pre-processor.
> >> It's easy to make a little Python script (or whatever language you
> >> prefer) that finds instances of HASH("this") and generates an include
> >> file that defines an enum with constants of the form "hash_this".  Your
> >> C code just includes this generated file, and has a macro definition of
> >> HASH that expands to the enum tag.
> >>
> >> At the risk of heresy, constexpr has made this sort of thing vastly
> >> easier in C++.
> >
> > Yes, I agree.
> > This is not so important, I can put the computed number instead of the macro.
> > I would use macro only if it was easy and clear.
> 
> Why can't you calculate it at runtime during initialisation? Or does it 
> have to be used in array bound or switch-case expressions?


Yes, I want to use in switch-case.
Otherwise I would use some function address to work as a "ID".

I suspect, I didn't check, that switch-cases are faster then if-elses because the compiler can create some table. 


[toc] | [prev] | [next] | [standalone]


#99394

FromBartC <bc@freeuk.com>
Date2016-12-14 20:06 +0000
Message-ID<o2s8la$utf$1@dont-email.me>
In reply to#99370
On 14/12/2016 19:26, Thiago Adams wrote:
> On Wednesday, December 14, 2016 at 5:20:39 PM UTC-2, Bart wrote:

>> Why can't you calculate it at runtime during initialisation? Or does it
>> have to be used in array bound or switch-case expressions?
>
>
> Yes, I want to use in switch-case.
> Otherwise I would use some function address to work as a "ID".
>
> I suspect, I didn't check, that switch-cases are faster then if-elses because the compiler can create some table.

Yes, if the values are localised.

But good hash values would be spread out and over a wide range making 
the use of a jump table harder.

If the strings are small however, say 4 characters or less, I might just 
use the character codes directly: 'this'. Although you'd have to check 
what different compilers do with multi-character literals like this.

Presumably you are looking up a hashed string against a set of 
pre-calculated hash values. I think you might be better off with an 
actual hash table, if the switch statement can't use the hash values 
profitably.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#99336

FromThiago Adams <thiago.adams@gmail.com>
Date2016-12-14 05:25 -0800
Message-ID<139c05b9-299f-4b55-ba6a-8fd4308c7ce4@googlegroups.com>
In reply to#99329
On Wednesday, December 14, 2016 at 9:52:02 AM UTC-2, Ben Bacarisse wrote:
> Thiago Adams  writes:
> 
> > Is it possible to do a sum with variadic macros?
> >
> > SUM('a', 'b', 'c') 
> >
> > I want to expand to 'a' + 'b' + 'c'
> 
> If you can accept a maximum number of arguments and the operation has an
> identity element you can so this:
> 
> #define sum(...) (sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0))
> #define sum2(a, b, c, d, e, f, g, h, ...) a + b + c + d + e + f + g + h
> 
> <snip>
> > What I was planning to do is to generate a hash.
> > HASH('t', 'h', 'i', 's');
> 
> Maybe.  That depends on the hash computation.
> 

This one:
https://en.wikipedia.org/wiki/Java_hashCode()

I think is the same of

HASH3(a, b, c)  ((a) << 5 << 5) + ((b) << 5)  + (c)


[toc] | [prev] | [next] | [standalone]


#99346

Frommark.bluemel@gmail.com
Date2016-12-14 08:10 -0800
Message-ID<5686c2f2-9736-44de-a66c-2125dfbf5875@googlegroups.com>
In reply to#99336
On Wednesday, 14 December 2016 13:25:24 UTC, Thiago Adams  wrote:

> This one:
> https://en.wikipedia.org/wiki/Java_hashCode()
> 
> I think is the same of
> 
> HASH3(a, b, c)  ((a) << 5 << 5) + ((b) << 5)  + (c)

I think you don't understand Java hashcodes.

[toc] | [prev] | [next] | [standalone]


#99350

FromThiago Adams <thiago.adams@gmail.com>
Date2016-12-14 08:23 -0800
Message-ID<ae949036-017c-4b63-a9b0-5ec0972ba898@googlegroups.com>
In reply to#99346
On Wednesday, December 14, 2016 at 2:10:28 PM UTC-2, mark.b...@gmail.com wrote:
> On Wednesday, 14 December 2016 13:25:24 UTC, Thiago Adams  wrote:
> 
> > This one:
> > https://en.wikipedia.org/wiki/Java_hashCode()
> > 
> > I think is the same of
> > 
> > HASH3(a, b, c)  ((a) << 5 << 5) + ((b) << 5)  + (c)
> 
> I think you don't understand Java hashcodes.

Fortunately, I am not using it yet. :)
In case I generate this hash outsize the program then I will use known hash implementation.

--

What would be a good string hash for C type names? 
Performance it's not a problem because it's computed in advance.
The computed hash will be used in switch cases. 32 bits. (unsigned int)





[toc] | [prev] | [next] | [standalone]


#99373

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-12-14 11:32 -0800
Message-ID<8e40c975-56cc-4458-a040-90e246f926f2@googlegroups.com>
In reply to#99350
On Wednesday, December 14, 2016 at 4:23:22 PM UTC, Thiago Adams wrote:

> What would be a good string hash for C type names? 
> Performance it's not a problem because it's computed in advance.
> The computed hash will be used in switch cases. 32 bits. (unsigned int)

Use perfect hashing.

https://en.wikipedia.org/wiki/Perfect_hash_function

If you have a closed list of names you can develop a hash function
that maps with no collisions. 

[toc] | [prev] | [next] | [standalone]


#99351

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-12-14 16:26 +0000
Message-ID<87oa0e79yp.fsf@bsb.me.uk>
In reply to#99336
Thiago Adams <thiago.adams@gmail.com> writes:

> On Wednesday, December 14, 2016 at 9:52:02 AM UTC-2, Ben Bacarisse wrote:
>> Thiago Adams  writes:
>> 
>> > Is it possible to do a sum with variadic macros?
>> >
>> > SUM('a', 'b', 'c') 
>> >
>> > I want to expand to 'a' + 'b' + 'c'
>> 
>> If you can accept a maximum number of arguments and the operation has an
>> identity element you can so this:
>> 
>> #define sum(...) (sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0))
>> #define sum2(a, b, c, d, e, f, g, h, ...) a + b + c + d + e + f + g + h
>> 
>> <snip>
>> > What I was planning to do is to generate a hash.
>> > HASH('t', 'h', 'i', 's');
>> 
>> Maybe.  That depends on the hash computation.
>> 
>
> This one:
> https://en.wikipedia.org/wiki/Java_hashCode()
>
> I think is the same of
>
> HASH3(a, b, c)  ((a) << 5 << 5) + ((b) << 5)  + (c)

If the order does not matter, this is reasonably simple:

#define sum(...) sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0))
#define sum2(a, b, c, d, e, f, ...) \
     ((((((((((f << 5) + e) << 5) + d) << 5) + c) << 5) + b) << 5) + a)

Add brackets (sorry, parentheses!) round a to f if you need to.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#99367

FromDavid Brown <david.brown@hesbynett.no>
Date2016-12-14 19:09 +0100
Message-ID<o2s1q1$4pv$1@dont-email.me>
In reply to#99351
On 14/12/16 17:26, Ben Bacarisse wrote:
> Thiago Adams <thiago.adams@gmail.com> writes:
>
>> On Wednesday, December 14, 2016 at 9:52:02 AM UTC-2, Ben Bacarisse wrote:
>>> Thiago Adams  writes:
>>>
>>>> Is it possible to do a sum with variadic macros?
>>>>
>>>> SUM('a', 'b', 'c')
>>>>
>>>> I want to expand to 'a' + 'b' + 'c'
>>>
>>> If you can accept a maximum number of arguments and the operation has an
>>> identity element you can so this:
>>>
>>> #define sum(...) (sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0))
>>> #define sum2(a, b, c, d, e, f, g, h, ...) a + b + c + d + e + f + g + h
>>>
>>> <snip>
>>>> What I was planning to do is to generate a hash.
>>>> HASH('t', 'h', 'i', 's');
>>>
>>> Maybe.  That depends on the hash computation.
>>>
>>
>> This one:
>> https://en.wikipedia.org/wiki/Java_hashCode()
>>
>> I think is the same of
>>
>> HASH3(a, b, c)  ((a) << 5 << 5) + ((b) << 5)  + (c)
>
> If the order does not matter, this is reasonably simple:
>
> #define sum(...) sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0))
> #define sum2(a, b, c, d, e, f, ...) \
>      ((((((((((f << 5) + e) << 5) + d) << 5) + c) << 5) + b) << 5) + a)
>

The trouble with this is that it is hopeless as a hash function if you 
need to go to more than 6 characters (assuming 32-bit integers).  Hash 
functions for strings are one of the few good uses of rotation instructions.

> Add brackets (sorry, parentheses!) round a to f if you need to.
>

[toc] | [prev] | [next] | [standalone]


#99374

Fromsupercat@casperkitty.com
Date2016-12-14 11:33 -0800
Message-ID<92af284b-15ff-41b0-97ea-027cedd62f27@googlegroups.com>
In reply to#99367
On Wednesday, December 14, 2016 at 12:09:31 PM UTC-6, David Brown wrote:
> On 14/12/16 17:26, Ben Bacarisse wrote:
> > Thiago Adams writes:
> >> This one:
> >> https://en.wikipedia.org/wiki/Java_hashCode()
> >>
> >> I think is the same of
> >>
> >> HASH3(a, b, c)  ((a) << 5 << 5) + ((b) << 5)  + (c)
> >
> > If the order does not matter, this is reasonably simple:
> >
> > #define sum(...) sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0))
> > #define sum2(a, b, c, d, e, f, ...) \
> >      ((((((((((f << 5) + e) << 5) + d) << 5) + c) << 5) + b) << 5) + a)
> >
> 
> The trouble with this is that it is hopeless as a hash function if you 
> need to go to more than 6 characters (assuming 32-bit integers).  Hash 
> functions for strings are one of the few good uses of rotation instructions.

Java's hash code scales by 31 rather than 32, so earlier characters don't
get totally lost.  While the multiply-and-add approach isn't wonderful, it
does offer the slight advantage that if one knows the hash codes of two
strings, the hashcode of the concatenation can be computed as 
hash1*(31**len2)+hash2 without having to examine all the contents of the
strings in question; computing x**y using modular integer arithmetic can
be easily accomplished in time O(lg(y)), though it's necessary to be a
little careful in C to ensure that integer promotions don't end up causing
Undefined Behavior.

[toc] | [prev] | [next] | [standalone]


#99378

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-12-14 19:40 +0000
Message-ID<877f72710p.fsf@bsb.me.uk>
In reply to#99367
David Brown <david.brown@hesbynett.no> writes:

> On 14/12/16 17:26, Ben Bacarisse wrote:
>> Thiago Adams <thiago.adams@gmail.com> writes:
<snip>
>>> HASH3(a, b, c)  ((a) << 5 << 5) + ((b) << 5)  + (c)
>>
>> If the order does not matter, this is reasonably simple:
>>
>> #define sum(...) sum2(__VA_ARGS__, 0, 0, 0, 0, 0, 0))
>> #define sum2(a, b, c, d, e, f, ...) \
>>      ((((((((((f << 5) + e) << 5) + d) << 5) + c) << 5) + b) << 5) + a)
>
> The trouble with this is that it is hopeless as a hash function if you
> need to go to more than 6 characters (assuming 32-bit integers).  Hash
> functions for strings are one of the few good uses of rotation
> instructions.

Sure, but I've no idea what the OP is using these for and it's not
impossible that the expression the OP gave works for the intended
purpose.

But in fact is was the "vararg shift" idea I wanted to show.  It's handy
to know.

-- 
Ben.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web