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


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

macro

Started bydspfun <dspfun@hotmail.com>
First post2012-01-15 05:29 -0800
Last post2012-01-16 12:01 +0000
Articles 20 on this page of 44 — 19 participants

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


Contents

  macro dspfun <dspfun@hotmail.com> - 2012-01-15 05:29 -0800
    Re: macro Dr Nick <3-nospam@temporary-address.org.uk> - 2012-01-15 13:44 +0000
      Re: macro dspfun <dspfun@hotmail.com> - 2012-01-15 05:58 -0800
        Re: macro "Joachim Schmitz" <nospam.jojo@schmitz-digital.de> - 2012-01-15 15:34 +0100
        Re: macro "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-01-15 06:37 -0800
          Re: macro dspfun <dspfun@hotmail.com> - 2012-01-15 07:28 -0800
            Re: macro Philip Lantz <prl@canterey.us> - 2012-01-15 17:30 -0800
              Re: macro Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-01-16 00:18 -0800
                Re: macro Hans Vlems <hvlems@freenet.de> - 2012-01-16 00:52 -0800
                  Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-16 22:08 +1300
                  Re: macro Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-01-16 03:04 -0800
                  Re: macro Markus Wichmann <nullplan@gmx.net> - 2012-01-16 12:42 +0100
          Re: macro jgk@panix.com (Joe keane) - 2012-01-16 14:48 +0000
            Re: macro Keith Thompson <kst-u@mib.org> - 2012-01-16 12:01 -0800
              Re: macro Philip Lantz <prl@canterey.us> - 2012-01-17 01:02 -0800
                Re: macro Keith Thompson <kst-u@mib.org> - 2012-01-17 13:05 -0800
                  Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-18 13:12 +1300
                    Re: macro dspfun <dspfun@hotmail.com> - 2012-01-18 01:05 -0800
                      Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-18 22:57 +1300
                        Re: macro "osmium" <r124c4u102@comcast.net> - 2012-01-18 06:22 -0600
                        Re: macro dspfun <dspfun@hotmail.com> - 2012-01-18 07:50 -0800
                          Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-20 14:09 +1300
                        Re: macro blp@cs.stanford.edu (Ben Pfaff) - 2012-01-18 11:28 -0800
                        Re: macro Kaz Kylheku <kaz@kylheku.com> - 2012-01-18 21:09 +0000
                          Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-20 15:08 +1300
                            [OT] Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-20 15:58 +1300
                              Re: [OT] Re: macro Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-20 12:22 +0000
                                Re: [OT] Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-21 07:58 +1300
                            Re: macro James Kuyper <jameskuyper@verizon.net> - 2012-01-19 22:47 -0500
                              Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-20 17:06 +1300
                                Re: macro James Kuyper <jameskuyper@verizon.net> - 2012-01-20 00:12 -0500
                                  Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-20 18:28 +1300
                            Re: macro Keith Thompson <kst-u@mib.org> - 2012-01-20 03:21 -0800
                          Re: macro Shao Miller <sha0.miller@gmail.com> - 2012-01-20 10:50 -0500
                            Re: macro Shao Miller <sha0.miller@gmail.com> - 2012-01-20 11:46 -0500
                        Re: macro Keith Thompson <kst-u@mib.org> - 2012-01-18 14:24 -0800
                        Re: macro jgk@panix.com (Joe keane) - 2012-01-18 22:36 +0000
                          Re: macro Kaz Kylheku <kaz@kylheku.com> - 2012-01-18 22:50 +0000
              Re: macro jgk@panix.com (Joe keane) - 2012-01-17 22:08 +0000
    Re: macro Keith Thompson <kst-u@mib.org> - 2012-01-15 08:00 -0800
    Re: macro NEON China BLUE <chine.bleu@yahoo.com> - 2012-01-15 08:15 -0800
    Re: macro Ian Collins <ian-news@hotmail.com> - 2012-01-16 09:04 +1300
      Re: macro Philip Lantz <prl@canterey.us> - 2012-01-15 17:36 -0800
    Re: macro Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-01-16 12:01 +0000

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#15908

Fromdspfun <dspfun@hotmail.com>
Date2012-01-18 07:50 -0800
Message-ID<306d1474-98ad-4ab0-a3b7-a64ef4555cf2@n6g2000vbz.googlegroups.com>
In reply to#15902
On 18 Jan, 10:57, Ian Collins <ian-n...@hotmail.com> wrote:
> On 01/18/12 10:05 PM, dspfun wrote:
>
> > On 18 Jan, 01:12, Ian Collins<ian-n...@hotmail.com>  wrote:
> >> On 01/18/12 10:05 AM, Keith Thompson wrote:
>
> [what adds these random lines?]
>
>
>
>
>
>
>
>
>
> >>> Philip Lantz<p...@canterey.us>    writes:
>
> >>>> I think one of the main reasons for me is that using do ... while (0) in
> >>>> a macro is a hack, and I try to avoid using hacks except where
> >>>> necessary, and it is (in my experience) almost never necessary.
>
> >>> Fair enough.
>
> >>> But one could argue that translating if/else to ?: and ";" to "," for
> >>> the sole purpose of making a chunk of code usable as a macro is equally
> >>> hackish.
>
> >>> Sure, "do...while(0)" is a hack -- but it's also an idiom that's widely
> >>> used and recognized by C programmers.
>
> >> It is also a strong indication that whatever you are attempting to do is
> >> an inappropriate use of a macro!
>
> > What is the reason that this is an indication that the "do...while(0)"
> > in a macro is an inappropriate use of a macro?
>
> Because in most cases it gets used where a function or as in your code,
> a macro wrapping a function, is more appropriate.  The rare exceptions
> are where macros are used as poor man's templates.
>
> I guess the use of "do...while(0)" (and function-like macros in general)
> is a hang over from 80s and 90s compiler which didn't inline functions.
>
> --
> Ian Collins

Thanks!

What would be an example of such a poor man's template?

Brs,
Markus

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


#15962

FromIan Collins <ian-news@hotmail.com>
Date2012-01-20 14:09 +1300
Message-ID<9nrt72F524U2@mid.individual.net>
In reply to#15908
On 01/19/12 04:50 AM, dspfun wrote:
>
> What would be an example of such a poor man's template?

Something like your typical min or max macros.

-- 
Ian Collins

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


#15919

Fromblp@cs.stanford.edu (Ben Pfaff)
Date2012-01-18 11:28 -0800
Message-ID<878vl4resl.fsf@blp.benpfaff.org>
In reply to#15902
Ian Collins <ian-news@hotmail.com> writes:

> I guess the use of "do...while(0)" (and function-like macros in
> general) is a hang over from 80s and 90s compiler which didn't inline
> functions.

Mostly.

In the tree I'm looking at now, I see two uses that don't fall
into that category.  The first is where I had a notion that
macros would generate better code, specifically for these macros:

    #define HASH_ROT(x, k) (((x) << (k)) | ((x) >> (32 - (k))))

    #define HASH_MIX(a, b, c)                       \
        do {                                        \
          a -= c; a ^= HASH_ROT(c,  4); c += b;     \
          b -= a; b ^= HASH_ROT(a,  6); a += c;     \
          c -= b; c ^= HASH_ROT(b,  8); b += a;     \
          a -= c; a ^= HASH_ROT(c, 16); c += b;     \
          b -= a; b ^= HASH_ROT(a, 19); a += c;     \
          c -= b; c ^= HASH_ROT(b,  4); b += a;     \
        } while (0)

    #define HASH_FINAL(a, b, c)                     \
        do {                                        \
          c ^= b; c -= HASH_ROT(b, 14);             \
          a ^= c; a -= HASH_ROT(c, 11);             \
          b ^= a; b -= HASH_ROT(a, 25);             \
          c ^= b; c -= HASH_ROT(b, 16);             \
          a ^= c; a -= HASH_ROT(c,  4);             \
          b ^= a; b -= HASH_ROT(a, 14);             \
          c ^= b; c -= HASH_ROT(b, 24);             \
        } while (0)

In an attempt to demonstrate that they do generate better code, I
converted them to the following inline functions:

    static inline uint32_t
    hash_rot(uint32_t x, int k)
    {
        return (x << k) | (x >> (32 - k));
    }

    static inline void
    hash_mix(uint32_t *a, uint32_t *b, uint32_t *c)
    {
          *a -= *c; *a ^= hash_rot(*c,  4); *c += *b;
          *b -= *a; *b ^= hash_rot(*a,  6); *a += *c;
          *c -= *b; *c ^= hash_rot(*b,  8); *b += *a;
          *a -= *c; *a ^= hash_rot(*c, 16); *c += *b;
          *b -= *a; *b ^= hash_rot(*a, 19); *a += *c;
          *c -= *b; *c ^= hash_rot(*b,  4); *b += *a;
    }

    static inline void
    hash_final(uint32_t *a, uint32_t *b, uint32_t *c)
    {
          *c ^= *b; *c -= hash_rot(*b, 14);
          *a ^= *c; *a -= hash_rot(*c, 11);
          *b ^= *a; *b -= hash_rot(*a, 25);
          *c ^= *b; *c -= hash_rot(*b, 16);
          *a ^= *c; *a -= hash_rot(*c,  4);
          *b ^= *a; *b -= hash_rot(*a, 14);
          *c ^= *b; *c -= hash_rot(*b, 24);
    }

(Of course this required some changes to the users also.)
However, when I looked at the generated code, it was completely
identical with GCC 4.4.5.  So I've now submitted a patch to
change these to inline functions:
        http://openvswitch.org/pipermail/dev/2012-January/014369.html

I ran out of time so I won't be able to describe my other use
case :-)
-- 
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}

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


#15921

FromKaz Kylheku <kaz@kylheku.com>
Date2012-01-18 21:09 +0000
Message-ID<20120118130142.908@kylheku.com>
In reply to#15902
On 2012-01-18, Ian Collins <ian-news@hotmail.com> wrote:
> Because in most cases it gets used where a function or as in your code, 
> a macro wrapping a function, is more appropriate.  The rare exceptions 
> are where macros are used as poor man's templates.
>
> I guess the use of "do...while(0)" (and function-like macros in general) 
> is a hang over from 80s and 90s compiler which didn't inline functions.

There are UUOM's (useless uses of macros) that can be replaced by functions.
But then there are function-like macros that cannot be written as functions.

If you don't write UUOM's in your code, then the remaining uses are hardly
rare exceptions. If you know what you're doing, 100% of your macros are
in fact necessary.

Here is a requirement:

  or(x, y)

This must evaluate X.  If X is nonzero, then the value X is the result, and Y
is not evaluated. Otherwise the result is the value of Y.  X is evaluated
exactly once, and Y at most once.

Good luck making a function for this.  Or even an entirely clean macro,
for that matter.

(Is that really "poor" man's template, by the way? Okay, show me the "rich"
man's C++ template for it, then.)

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


#15963

FromIan Collins <ian-news@hotmail.com>
Date2012-01-20 15:08 +1300
Message-ID<9ns0koF524U3@mid.individual.net>
In reply to#15921
On 01/19/12 10:09 AM, Kaz Kylheku wrote:
> On 2012-01-18, Ian Collins<ian-news@hotmail.com>  wrote:
>> Because in most cases it gets used where a function or as in your code,
>> a macro wrapping a function, is more appropriate.  The rare exceptions
>> are where macros are used as poor man's templates.
>>
>> I guess the use of "do...while(0)" (and function-like macros in general)
>> is a hang over from 80s and 90s compiler which didn't inline functions.
>
> There are UUOM's (useless uses of macros) that can be replaced by functions.
> But then there are function-like macros that cannot be written as functions.
>
> If you don't write UUOM's in your code, then the remaining uses are hardly
> rare exceptions. If you know what you're doing, 100% of your macros are
> in fact necessary.
>
> Here is a requirement:
>
>    or(x, y)
>
> This must evaluate X.  If X is nonzero, then the value X is the result, and Y
> is not evaluated. Otherwise the result is the value of Y.  X is evaluated
> exactly once, and Y at most once.
>
> Good luck making a function for this.  Or even an entirely clean macro,
> for that matter.
>
> (Is that really "poor" man's template, by the way? Okay, show me the "rich"
> man's C++ template for it, then.)

Not really, at least for c++03.  With C++0x I guess you could use a 
simple variable arguments template if both expressions are the same type:

template <typename Fn, typename... Args>
bool do_or( bool b, Fn fn, Args... args)
{
   if( b ) return b;

   return fn( args... );
}

Life gets more interesting when they are different types.

-- 
Ian Collins

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


#15965 — [OT] Re: macro

FromIan Collins <ian-news@hotmail.com>
Date2012-01-20 15:58 +1300
Subject[OT] Re: macro
Message-ID<9ns3j4F524U4@mid.individual.net>
In reply to#15963
On 01/20/12 03:08 PM, Ian Collins wrote:
> On 01/19/12 10:09 AM, Kaz Kylheku wrote:
>>
>> Here is a requirement:
>>
>>     or(x, y)
>>
>> This must evaluate X.  If X is nonzero, then the value X is the result, and Y
>> is not evaluated. Otherwise the result is the value of Y.  X is evaluated
>> exactly once, and Y at most once.
>>
>> Good luck making a function for this.  Or even an entirely clean macro,
>> for that matter.
>>
>> (Is that really "poor" man's template, by the way? Okay, show me the "rich"
>> man's C++ template for it, then.)
>
> Not really, at least for c++03.  With C++0x I guess you could use a
> simple variable arguments template if both expressions are the same type:
>
> template<typename Fn, typename... Args>
> bool do_or( bool b, Fn fn, Args... args)
> {
>     if( b ) return b;
>
>     return fn( args... );
> }
>
> Life gets more interesting when they are different types.

I couldn't resist following this up, so here's a rather OT C++0x solution:

template <typename X, typename Y, typename... Args>
auto do_or( X x, Y y, Args... args ) -> decltype(x+y( args...))
{
   if( x ) return x;

   return y( args...);
}

-- 
Ian Collins

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


#15974 — Re: [OT] Re: macro

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-01-20 12:22 +0000
SubjectRe: [OT] Re: macro
Message-ID<0.840318e8171f503ababc.20120120122206GMT.878vl2lg29.fsf@bsb.me.uk>
In reply to#15965
Ian Collins <ian-news@hotmail.com> writes:
>> On 01/19/12 10:09 AM, Kaz Kylheku wrote:
>>>
>>> Here is a requirement:
>>>
>>>     or(x, y)
>>>
>>> This must evaluate X.  If X is nonzero, then the value X is the
>>> result, and Y is not evaluated. Otherwise the result is the value of
>>> Y.  X is evaluated exactly once, and Y at most once.
<snip>
> I couldn't resist following this up, so here's a rather OT C++0x solution:
>
> template <typename X, typename Y, typename... Args>
> auto do_or( X x, Y y, Args... args ) -> decltype(x+y( args...))
> {
>   if( x ) return x;
>
>   return y( args...);
> }

This may be a close as one can get (I can't get any closer!) but it
doesn't strike me as being "a solution" because of the need to wrap the
original expression, y, in a function to delay its execution.  C++11's
lambdas make this simple enough, but it still won't look as readable as
the original:

    do_or(a++, [&b]{return b++;})
vs
    or(a++, b++)

That may, however, be an advantage, since having odd evaluation semantics
for the arguments of something that looks like a function is asking for
trouble.  (Yes, I know it was posed as an academic exercise so this is
an incidental point).

BTW, what's the purpose of the extra args?  I'd have though that the
availability of lambdas renders these unnecessary.  If it's to allow a
non-lambda function as a wrapper for the expression, then would you not
need to write Args &... args to allow for modification?

-- 
Ben.

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


#15981 — Re: [OT] Re: macro

FromIan Collins <ian-news@hotmail.com>
Date2012-01-21 07:58 +1300
SubjectRe: [OT] Re: macro
Message-ID<9ntrq3F524U8@mid.individual.net>
In reply to#15974
On 01/21/12 01:22 AM, Ben Bacarisse wrote:
> Ian Collins<ian-news@hotmail.com>  writes:
>>> On 01/19/12 10:09 AM, Kaz Kylheku wrote:
>>>>
>>>> Here is a requirement:
>>>>
>>>>      or(x, y)
>>>>
>>>> This must evaluate X.  If X is nonzero, then the value X is the
>>>> result, and Y is not evaluated. Otherwise the result is the value of
>>>> Y.  X is evaluated exactly once, and Y at most once.
> <snip>
>> I couldn't resist following this up, so here's a rather OT C++0x solution:
>>
>> template<typename X, typename Y, typename... Args>
>> auto do_or( X x, Y y, Args... args ) ->  decltype(x+y( args...))
>> {
>>    if( x ) return x;
>>
>>    return y( args...);
>> }
>
> This may be a close as one can get (I can't get any closer!) but it
> doesn't strike me as being "a solution" because of the need to wrap the
> original expression, y, in a function to delay its execution.  C++11's
> lambdas make this simple enough, but it still won't look as readable as
> the original:
>
>      do_or(a++, [&b]{return b++;})
> vs
>      or(a++, b++)
>
> That may, however, be an advantage, since having odd evaluation semantics
> for the arguments of something that looks like a function is asking for
> trouble.  (Yes, I know it was posed as an academic exercise so this is
> an incidental point).
>
> BTW, what's the purpose of the extra args?  I'd have though that the
> availability of lambdas renders these unnecessary.  If it's to allow a
> non-lambda function as a wrapper for the expression, then would you not
> need to write Args&... args to allow for modification?

I overlooked the lambdas.

-- 
Ian Collins

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


#15967

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-01-19 22:47 -0500
Message-ID<jfao4h$8ph$1@dont-email.me>
In reply to#15963
On 01/19/2012 09:08 PM, Ian Collins wrote:
> On 01/19/12 10:09 AM, Kaz Kylheku wrote:
>> On 2012-01-18, Ian Collins<ian-news@hotmail.com>  wrote:
>>> Because in most cases it gets used where a function or as in your code,
>>> a macro wrapping a function, is more appropriate.
...
>> Here is a requirement:
>>
>>    or(x, y)
>>
>> This must evaluate X.  If X is nonzero, then the value X is the result, and Y
>> is not evaluated. Otherwise the result is the value of Y.  X is evaluated
>> exactly once, and Y at most once.
>>
>> Good luck making a function for this.  Or even an entirely clean macro,
>> for that matter.
>>
>> (Is that really "poor" man's template, by the way? Okay, show me the "rich"
>> man's C++ template for it, then.)

There's a trivial problem with the suggestion of using C++ to implement
or(): 'or' is keyword in C++, with the same meaning as the 'or' #defined
by <iso646.h> in C. Any attempt to define any identifier with that name
would fail, usually by being interpreted as a syntax error. So let's
change the name of the requested function to Or().

> Not really, at least for c++03.  With C++0x I guess you could use a 
> simple variable arguments template if both expressions are the same type:
> 
> template <typename Fn, typename... Args>
> bool do_or( bool b, Fn fn, Args... args)
> {
>    if( b ) return b;
> 
>    return fn( args... );
> }
> 
> Life gets more interesting when they are different types.

So, could you show how a non-macro implementation of 'Or()' could built
in C++ from do_or()? Let's be more specific. Given

	int a=2;

How could Or(1,a++) implemented, so as to prevent evaluation of a++?
-- 
James Kuyper

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


#15968

FromIan Collins <ian-news@hotmail.com>
Date2012-01-20 17:06 +1300
Message-ID<9ns7i5F524U6@mid.individual.net>
In reply to#15967
On 01/20/12 04:47 PM, James Kuyper wrote:
> On 01/19/2012 09:08 PM, Ian Collins wrote:
>> On 01/19/12 10:09 AM, Kaz Kylheku wrote:
>>> On 2012-01-18, Ian Collins<ian-news@hotmail.com>   wrote:
>>>> Because in most cases it gets used where a function or as in your code,
>>>> a macro wrapping a function, is more appropriate.
> ....
>>> Here is a requirement:
>>>
>>>     or(x, y)
>>>
>>> This must evaluate X.  If X is nonzero, then the value X is the result, and Y
>>> is not evaluated. Otherwise the result is the value of Y.  X is evaluated
>>> exactly once, and Y at most once.
>>>
>>> Good luck making a function for this.  Or even an entirely clean macro,
>>> for that matter.
>>>
>>> (Is that really "poor" man's template, by the way? Okay, show me the "rich"
>>> man's C++ template for it, then.)
>
> There's a trivial problem with the suggestion of using C++ to implement
> or(): 'or' is keyword in C++, with the same meaning as the 'or' #defined
> by<iso646.h>  in C. Any attempt to define any identifier with that name
> would fail, usually by being interpreted as a syntax error. So let's
> change the name of the requested function to Or().
>
>> Not really, at least for c++03.  With C++0x I guess you could use a
>> simple variable arguments template if both expressions are the same type:
>>
>> template<typename Fn, typename... Args>
>> bool do_or( bool b, Fn fn, Args... args)
>> {
>>     if( b ) return b;
>>
>>     return fn( args... );
>> }
>>
>> Life gets more interesting when they are different types.
>
> So, could you show how a non-macro implementation of 'Or()' could built
> in C++ from do_or()? Let's be more specific. Given
>
> 	int a=2;
>
> How could Or(1,a++) implemented, so as to prevent evaluation of a++?

I don't see how it can, a++ will always be evaluated as a function 
parameter in either language.

-- 
Ian Collins

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


#15969

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-01-20 00:12 -0500
Message-ID<jfat42$t2p$1@dont-email.me>
In reply to#15968
On 01/19/2012 11:06 PM, Ian Collins wrote:
> On 01/20/12 04:47 PM, James Kuyper wrote:
>> On 01/19/2012 09:08 PM, Ian Collins wrote:
>>> On 01/19/12 10:09 AM, Kaz Kylheku wrote:
...
>>>> Here is a requirement:
>>>>
>>>>     or(x, y)
>>>>
>>>> This must evaluate X.  If X is nonzero, then the value X is the result, and Y
>>>> is not evaluated. Otherwise the result is the value of Y.  X is evaluated
>>>> exactly once, and Y at most once.
>>>>
>>>> Good luck making a function for this.  Or even an entirely clean macro,
>>>> for that matter.
>>>>
>>>> (Is that really "poor" man's template, by the way? Okay, show me the "rich"
>>>> man's C++ template for it, then.)
>>
>> There's a trivial problem with the suggestion of using C++ to implement
>> or(): 'or' is keyword in C++, with the same meaning as the 'or' #defined
>> by<iso646.h>  in C. Any attempt to define any identifier with that name
>> would fail, usually by being interpreted as a syntax error. So let's
>> change the name of the requested function to Or().
>>
>>> Not really, at least for c++03.  With C++0x I guess you could use a
>>> simple variable arguments template if both expressions are the same type:
...
>>> Life gets more interesting when they are different types.
>>
>> So, could you show how a non-macro implementation of 'Or()' could built
>> in C++ from do_or()? Let's be more specific. Given
>>
>> 	int a=2;
>>
>> How could Or(1,a++) implemented, so as to prevent evaluation of a++?
> 
> I don't see how it can, a++ will always be evaluated as a function 
> parameter in either language.

That was precisely the point Kaz was making. He's suggesting that it can
be implemented using a macro, though I'm not quite sure how that would work.

The key point is that controlling the number of times that an argument
gets evaluated is possible for macros, but not for functions.

What this has to do with the do {...} while(0) idiom, I have no idea,
since no matter how Or() is implemented, it certainly can't be
implemented by use of that idiom, since it doesn't allow returning a value.
-- 
James Kuyper

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


#15971

FromIan Collins <ian-news@hotmail.com>
Date2012-01-20 18:28 +1300
Message-ID<9nscbeF524U7@mid.individual.net>
In reply to#15969
On 01/20/12 06:12 PM, James Kuyper wrote:
> On 01/19/2012 11:06 PM, Ian Collins wrote:
>> On 01/20/12 04:47 PM, James Kuyper wrote:
>>> On 01/19/2012 09:08 PM, Ian Collins wrote:
>>>> On 01/19/12 10:09 AM, Kaz Kylheku wrote:
> ....
>>>>> Here is a requirement:
>>>>>
>>>>>      or(x, y)
>>>>>
>>>>> This must evaluate X.  If X is nonzero, then the value X is the result, and Y
>>>>> is not evaluated. Otherwise the result is the value of Y.  X is evaluated
>>>>> exactly once, and Y at most once.
>>>>>
>>>>> Good luck making a function for this.  Or even an entirely clean macro,
>>>>> for that matter.
>>>>>
>>>>> (Is that really "poor" man's template, by the way? Okay, show me the "rich"
>>>>> man's C++ template for it, then.)
>>>
>>> There's a trivial problem with the suggestion of using C++ to implement
>>> or(): 'or' is keyword in C++, with the same meaning as the 'or' #defined
>>> by<iso646.h>   in C. Any attempt to define any identifier with that name
>>> would fail, usually by being interpreted as a syntax error. So let's
>>> change the name of the requested function to Or().
>>>
>>>> Not really, at least for c++03.  With C++0x I guess you could use a
>>>> simple variable arguments template if both expressions are the same type:
> ....
>>>> Life gets more interesting when they are different types.
>>>
>>> So, could you show how a non-macro implementation of 'Or()' could built
>>> in C++ from do_or()? Let's be more specific. Given
>>>
>>> 	int a=2;
>>>
>>> How could Or(1,a++) implemented, so as to prevent evaluation of a++?
>>
>> I don't see how it can, a++ will always be evaluated as a function
>> parameter in either language.
>
> That was precisely the point Kaz was making. He's suggesting that it can
> be implemented using a macro, though I'm not quite sure how that would work.
>
> The key point is that controlling the number of times that an argument
> gets evaluated is possible for macros, but not for functions.

I'd like to see a macro solution for this problem, I don't see how it 
could work considering the value of the first argument isn't known at 
compile time.

I would also like to see a macro solution where the two arguments are 
function calls.

The addition of automatic return type deduction and variable argument 
templates increases the utility of templates in areas where macros were 
the only option.

> What this has to do with the do {...} while(0) idiom, I have no idea,
> since no matter how Or() is implemented, it certainly can't be
> implemented by use of that idiom, since it doesn't allow returning a value.

:)

-- 
Ian Collins

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


#15973

FromKeith Thompson <kst-u@mib.org>
Date2012-01-20 03:21 -0800
Message-ID<lnbopyy5yv.fsf@nuthaus.mib.org>
In reply to#15963
Ian Collins <ian-news@hotmail.com> writes:
[snip]
> Not really, at least for c++03.  With C++0x I guess you could use a 
> simple variable arguments template if both expressions are the same type:
[snip]

C++0x is now C++11.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#15978

FromShao Miller <sha0.miller@gmail.com>
Date2012-01-20 10:50 -0500
Message-ID<jfc2jq$eoo$1@dont-email.me>
In reply to#15921
On 1/18/2012 16:09, Kaz Kylheku wrote:
>[...]
> Here is a requirement:
>
>    or(x, y)
>
> This must evaluate X.  If X is nonzero, then the value X is the result, and Y
> is not evaluated. Otherwise the result is the value of Y.  X is evaluated
> exactly once, and Y at most once.
>
> Good luck making a function for this.  Or even an entirely clean macro,
> for that matter.
> [...]

Well, I don't know a lot about C++, but in C1X, I think you might be 
able to get close with the code below.  I think it could be simplified a 
lot if there was a C '_TypeOf'!

I've commented out the '_Thread_local' as I guess that's for C > C1X.

Some restrictions apply:
- There are only certain, specified, supported types for the 'M_OR' 
macro arguments.
- If the 'M_OR' macro invocation is indeterminately sequenced relative 
to another 'M_OR' macro invocation, the behaviour is undefined.
- Without '_Thread_local', use of 'M_OR' is not thread-safe.
- Other stuff I'm forgetting at the moment, but you folks will notice, 
I'm sure.

Here is the code:

   #include <stddef.h>
   #include <stdio.h>

   #define M_COPY_OF_TYPES_(u_, m_) \
     u_(unsigned char, m_) \
     u_(signed char, m_) \
     u_(char, m_) \
     u_(unsigned short, m_) \
     u_(signed short, m_) \
     u_(unsigned int, m_) \
     u_(signed int, m_) \
     u_(unsigned long, m_) \
     u_(signed long, m_) \
     u_(float, m_) \
     u_(double, m_)

   #define M_COPY_OF_CASE_(t_, m_) \
     t_: \
       (t_[1]) { _Generic(m_, t_: m_, default: 0) },

   #define M_COPY_OF(x_) ( \
       _Generic( \
           (x_), \
           M_COPY_OF_TYPES_(M_COPY_OF_CASE_, (x_)) \
           default: \
             0 \
         ) \
     )

   #if 0
   _Thread_local static void * or_helper_;
   #endif
   static void * or_helper_;

   #define M_OR_HELPER_GET_CASE_(t_, m_) \
     t_: \
       (t_ *) or_helper_,

   #define M_OR_HELPER_GET_(x_) ( \
     _Generic( \
         (x_), \
         M_COPY_OF_TYPES_(M_OR_HELPER_GET_CASE_, (x_)) \
         default: \
           0 \
       ) \
     )

   #define M_OR_HELPER_SET_(x_) ( \
       (or_helper_ = M_COPY_OF(x_)), \
       M_OR_HELPER_GET_(x_) \
     )

   #define M_OR(x_, y_) ( \
       *M_OR_HELPER_SET_(x_) ? *M_OR_HELPER_GET_(x_) : (y_) \
     )

   int main(void) {
       int x;
       int * ip;
       float y, z;
       float * fp;

       puts("M_COPY_OF demonstrations:");
       x = 42;
       ip = M_COPY_OF(x++);
       printf("x == %d && *ip == %d\n", x, *ip);

       ip = M_COPY_OF(13);
       printf("*ip == %d\n", *ip);

       fp = M_COPY_OF(3.14f);
       printf("*fp == %f\n", *fp);

       puts("");

       x = 2;
       y = 3.14;
       printf("Initial conditions: x == %d && y == %f\n", x, y);

       z = M_OR(x--, y++);
       printf(
           "After first M_OR: x == %d && y == %f && z == %f\n",
           x,
           y,
           z
         );

       z = M_OR(x--, y++);
       printf(
           "After second M_OR: x == %d && y == %f && z == %f\n",
           x,
           y,
           z
         );

       z = M_OR(x--, y++);
       printf(
           "After third M_OR: x == %d && y == %f && z == %f\n",
           x,
           y,
           z
         );

       return 0;
     }

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


#15980

FromShao Miller <sha0.miller@gmail.com>
Date2012-01-20 11:46 -0500
Message-ID<jfc5t6$1ij$1@dont-email.me>
In reply to#15978
On 1/20/2012 10:50, Shao Miller wrote:
> Some restrictions apply:
> - There are only certain, specified, supported types for the 'M_OR'
> macro arguments.
> - If the 'M_OR' macro invocation is indeterminately sequenced relative
> to another 'M_OR' macro invocation, the behaviour is undefined.

I meant "unsequenced."  Sorry about that.

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


#15925

FromKeith Thompson <kst-u@mib.org>
Date2012-01-18 14:24 -0800
Message-ID<ln1uqwzm19.fsf@nuthaus.mib.org>
In reply to#15902
Ian Collins <ian-news@hotmail.com> writes:
> On 01/18/12 10:05 PM, dspfun wrote:
>> On 18 Jan, 01:12, Ian Collins<ian-n...@hotmail.com>  wrote:
>>> On 01/18/12 10:05 AM, Keith Thompson wrote:
>
> [what adds these random lines?]

Do you mean the blank lines that you didn't quote?  It looked like you
were complaining about the attribution lines (which I'm sure you
wouldn't do).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


#15927

Fromjgk@panix.com (Joe keane)
Date2012-01-18 22:36 +0000
Message-ID<jf7hhg$5lq$1@reader1.panix.com>
In reply to#15902
In article <9nnjboFaaoU3@mid.individual.net>,
Ian Collins  <ian-news@hotmail.com> wrote:
>I guess the use of "do...while(0)" (and function-like macros in general) 
>is a hang over from 80s and 90s compiler which didn't inline functions.

Talking today, if someone said 'doesn't inline function work well?'
[assuming it works well] i'd say 'well yeah, inline function is great'.

I think people learned how to do stuff with macros [that is, if you
aren't adept at reading/writing macros, you don't really know C], then
they learned that inline function is available everywhere.

"If the macros work well, why do we want inline function, we will stick
with the stuff we are used to."

I wonder if this will change over time, where more people can't think of
a day when inline functions are not universal.  Maybe a bit, but i don't
think it's going to a world where almost everyone doesn't use macros and
doesn't really understand them.

I think this is a feature that C inherited from C++.  It seems to me,
once C++ had inline function and it worked, then everyone in C world
said 'well yeah, let's put that in'.  Oh and, Stroustrup said his goal
is to reduce use of the preprocessor.

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


#15928

FromKaz Kylheku <kaz@kylheku.com>
Date2012-01-18 22:50 +0000
Message-ID<20120118143741.283@kylheku.com>
In reply to#15927
On 2012-01-18, Joe keane <jgk@panix.com> wrote:
> In article <9nnjboFaaoU3@mid.individual.net>,
> Ian Collins  <ian-news@hotmail.com> wrote:
>>I guess the use of "do...while(0)" (and function-like macros in general) 
>>is a hang over from 80s and 90s compiler which didn't inline functions.
>
> Talking today, if someone said 'doesn't inline function work well?'
> [assuming it works well] i'd say 'well yeah, inline function is great'.
>
> I think people learned how to do stuff with macros [that is, if you
> aren't adept at reading/writing macros, you don't really know C], then
> they learned that inline function is available everywhere.
>
> "If the macros work well, why do we want inline function, we will stick
> with the stuff we are used to."

Even if inline isn't available, you can use static functions as a fallback.

In one freeware program that I maintain, I have a configure test for
various ways of doing inline, in a particular order. Two source files
are written written defining the same inline function and linked
together, to verify that the chosen method is not only accepted as
a valid function definition, but will not cause multiple definition clashes
when it is pulled into multiple translation units:

printf "Checking how to declare inline functions ... "

if [ -z "$inline" ] ; then
  for inline in \
    "inline" "static inline" "extern inline" \
    "__inline__" "static __inline__" "extern __inline__" \
    "static"
  do
    cat > conftest1.c <<!
$inline int func(void)
{
  return 0;
}

int main(void)
{
  return func();
}
!
    cat > conftest2.c <<!
$inline int func(void)
{
  return 0;
}
!
    rm -f conftest2
    if ! make conftest2 > conftest.err 2>&1 ; then
	continue
    fi
    break
  done
fi

printf '"%s"\n' "$inline"
printf "#define INLINE $inline\n" >> config.h

If there is no inline, and the compiler doesn't automatically inline
small static functions, you get code bloat.  Get a better compiler for my
program, or live with the bloated code.

When configuring with GCC's gcc, since I don't use the C99 dialect, guess which
item on that list works?  Everything fails right up until "static __inline__".
With GCC's g++, "inline" tests successfully, of course.

> I wonder if this will change over time, where more people can't think of
> a day when inline functions are not universal.  

Even if inline functions aren't universal, INLINE functions can be. :)

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


#15893

Fromjgk@panix.com (Joe keane)
Date2012-01-17 22:08 +0000
Message-ID<jf4rgs$h1a$1@reader1.panix.com>
In reply to#15851
In article <lnhazv1kon.fsf@nuthaus.mib.org>,
Keith Thompson  <kst-u@mib.org> wrote:
>If you were writing this other than as a macro, presumably you'd use the
>if/else from rather than using the conditional operator, simply because
>it's more readable that way.

If you saw code like this:

	if (x > y)
	    z = x;
	else
	    z = y;

would you think it's a bit silly?

>But what if you happen to know that you're *never* going to need to use
>it other than in a statement context?

IMHE 'never' means about 50% of the time you will find something you
hadn't thought of.

>Why not write the macro definition in a more readable and maintainable
>form, when the only cost is the loss of some flexibility that you're
>never going to use anyway?

It's not less readable *to me*.  Admittedly, i've done this sort of
thing a lot.  For a newbie it might make him woozy.

There's a place for statement macros.  When it's next to impossible to
make an expression macro, or it's so horribly unreadable that it makes
*me* woozy, i don't have a problem with it.

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


#15820

FromKeith Thompson <kst-u@mib.org>
Date2012-01-15 08:00 -0800
Message-ID<lnwr8t0xd2.fsf@nuthaus.mib.org>
In reply to#15813
dspfun <dspfun@hotmail.com> writes:

> Can you see anything wrong or "bad" with the following macro?
>
> #define LOG(level, msg) \
> openlog (__FUNCTION__, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
> \
> syslog (level, "%s", msg);\
> closelog ();
>
> I have problems using the macro with ternary operators. I believe it
> should have parantheses around it all, but I cannot get it right.

If you want the macro to be usable *as a statement*, you
should use the do ... while (0) trick; see question 10.4
in the comp.lang.c FAQ, http://c-faq.com/.  Each occurrence
of any parameter name in the macro should be in parentheses.
See <https://github.com/Keith-S-Thompson/42> for an example of what
can happen if you don't follow this rule.

If you need to to be usable *as an expression*, you can't use
do/while -- but you can use the comma operator.  In addition to
parenthesizing each parameter reference, the entire definition
should be enclosed in parentheses.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

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


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

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


csiph-web