* macros: "do-while" versus "({ })" and a compile-time error
@ 2007-01-08 18:50 Robert P. J. Day
2007-01-09 17:08 ` H. Peter Anvin
2007-01-09 17:33 ` Stefan Richter
0 siblings, 2 replies; 12+ messages in thread
From: Robert P. J. Day @ 2007-01-08 18:50 UTC (permalink / raw)
To: Linux kernel mailing list
just to stir the pot a bit regarding the discussion of the two
different ways to define macros, i've just noticed that the "({ })"
notation is not universally acceptable. i've seen examples where
using that notation causes gcc to produce:
error: braced-group within expression allowed only inside a function
i wasn't aware that there were limits on this notation. can someone
clarify this? under what circumstances *can't* you use that notation?
thanks.
rday
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-08 18:50 macros: "do-while" versus "({ })" and a compile-time error Robert P. J. Day @ 2007-01-09 17:08 ` H. Peter Anvin 2007-01-09 17:33 ` Stefan Richter 1 sibling, 0 replies; 12+ messages in thread From: H. Peter Anvin @ 2007-01-09 17:08 UTC (permalink / raw) To: Robert P. J. Day; +Cc: Linux kernel mailing list Robert P. J. Day wrote: > just to stir the pot a bit regarding the discussion of the two > different ways to define macros, i've just noticed that the "({ })" > notation is not universally acceptable. i've seen examples where > using that notation causes gcc to produce: > > error: braced-group within expression allowed only inside a function > > i wasn't aware that there were limits on this notation. can someone > clarify this? under what circumstances *can't* you use that notation? > thanks. > Well, you can apparently not use it as a part of a constant expression (which makes sense; do-while is illegal there too.) That would be the only case in which an expression is permitted outside a function at all. -hpa ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-08 18:50 macros: "do-while" versus "({ })" and a compile-time error Robert P. J. Day 2007-01-09 17:08 ` H. Peter Anvin @ 2007-01-09 17:33 ` Stefan Richter 2007-01-09 19:23 ` linux-os (Dick Johnson) 1 sibling, 1 reply; 12+ messages in thread From: Stefan Richter @ 2007-01-09 17:33 UTC (permalink / raw) To: Robert P. J. Day; +Cc: Linux kernel mailing list Robert P. J. Day wrote: > just to stir the pot a bit regarding the discussion of the two > different ways to define macros, You mean function-like macros, right? > i've just noticed that the "({ })" > notation is not universally acceptable. i've seen examples where > using that notation causes gcc to produce: > > error: braced-group within expression allowed only inside a function And function calls and macros which expand to "do { expr; } while (0)" won't work anywhere outside of functions either. > i wasn't aware that there were limits on this notation. can someone > clarify this? under what circumstances *can't* you use that notation? > thanks. The limitations are certainly highly compiler-specific. -- Stefan Richter -=====-=-=== ---= -=--= http://arcgraph.de/sr/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-09 17:33 ` Stefan Richter @ 2007-01-09 19:23 ` linux-os (Dick Johnson) 2007-01-09 20:19 ` Stefan Richter 2007-01-10 6:20 ` Robert P. J. Day 0 siblings, 2 replies; 12+ messages in thread From: linux-os (Dick Johnson) @ 2007-01-09 19:23 UTC (permalink / raw) To: Stefan Richter; +Cc: Robert P. J. Day, Linux kernel mailing list On Tue, 9 Jan 2007, Stefan Richter wrote: > Robert P. J. Day wrote: >> just to stir the pot a bit regarding the discussion of the two >> different ways to define macros, > > You mean function-like macros, right? > >> i've just noticed that the "({ })" >> notation is not universally acceptable. i've seen examples where >> using that notation causes gcc to produce: >> >> error: braced-group within expression allowed only inside a function > > And function calls and macros which expand to "do { expr; } while (0)" > won't work anywhere outside of functions either. > >> i wasn't aware that there were limits on this notation. can someone >> clarify this? under what circumstances *can't* you use that notation? >> thanks. > > The limitations are certainly highly compiler-specific. I don't think so. You certainly couldn't write working 'C' code like this: do { a = 1; } while(0); This _needs_ to be inside a function. In fact any runtime operations need to be inside functions. It's only in assembly that you could 'roll your own' code like: main: ret 0 Most of these errors come about as a result of changes where a macro used to define a constant. Later on, it was no longer a constant in code that didn't actually get compiled during the testing. Cheers, Dick Johnson Penguin : Linux version 2.6.16.24 on an i686 machine (5592.72 BogoMips). New book: http://www.AbominableFirebug.com/ _ \x1a\x04 **************************************************************** The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-09 19:23 ` linux-os (Dick Johnson) @ 2007-01-09 20:19 ` Stefan Richter 2007-01-10 6:20 ` Robert P. J. Day 1 sibling, 0 replies; 12+ messages in thread From: Stefan Richter @ 2007-01-09 20:19 UTC (permalink / raw) To: linux-os (Dick Johnson); +Cc: Robert P. J. Day, Linux kernel mailing list linux-os (Dick Johnson) wrote: > On Tue, 9 Jan 2007, Stefan Richter wrote: >> The limitations are certainly highly compiler-specific. > > I don't think so. I referred to the ({ expr; }) in this remark, not to do-while. It's not a valid construct in many flavors of the C language in the first place. Also, occurrences of ({ expr; }) could be expandable to a constant expression but would still not be accepted by gcc's parser outside of functions. -- Stefan Richter -=====-=-=== ---= -=--= http://arcgraph.de/sr/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-09 19:23 ` linux-os (Dick Johnson) 2007-01-09 20:19 ` Stefan Richter @ 2007-01-10 6:20 ` Robert P. J. Day 2007-01-10 12:16 ` linux-os (Dick Johnson) 1 sibling, 1 reply; 12+ messages in thread From: Robert P. J. Day @ 2007-01-10 6:20 UTC (permalink / raw) To: linux-os (Dick Johnson); +Cc: Stefan Richter, Linux kernel mailing list On Tue, 9 Jan 2007, linux-os (Dick Johnson) wrote: > > On Tue, 9 Jan 2007, Stefan Richter wrote: > > > Robert P. J. Day wrote: > >> just to stir the pot a bit regarding the discussion of the two > >> different ways to define macros, > > > > You mean function-like macros, right? > > > >> i've just noticed that the "({ })" > >> notation is not universally acceptable. i've seen examples where > >> using that notation causes gcc to produce: > >> > >> error: braced-group within expression allowed only inside a function > > > > And function calls and macros which expand to "do { expr; } while (0)" > > won't work anywhere outside of functions either. > > > >> i wasn't aware that there were limits on this notation. can someone > >> clarify this? under what circumstances *can't* you use that notation? > >> thanks. > > > > The limitations are certainly highly compiler-specific. > > I don't think so. You certainly couldn't write working 'C' code like > this: > > do { a = 1; } while(0); > > This _needs_ to be inside a function. In fact any runtime operations > need to be inside functions. It's only in assembly that you could > 'roll your own' code like: > > main: > ret 0 > > > Most of these errors come about as a result of changes where a macro > used to define a constant. Later on, it was no longer a constant in > code that didn't actually get compiled during the testing. just FYI, the reason i brought this up in the first place is that i noticed that the ALIGN() macro in kernel.h didn't verify that the alignment value was a power of 2, so i thought -- hmmm, i wonder if there are any invocations where that's not true, so i (temporarily) rewrote ALIGN to incorporate that check, and the build blew up including include/net/neighbour.h, which contains the out-of-function declaration: struct neighbour { ... unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; ... so it's not a big deal, it was just me goofing around and breaking things. rday ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-10 6:20 ` Robert P. J. Day @ 2007-01-10 12:16 ` linux-os (Dick Johnson) 2007-01-10 13:46 ` Robert P. J. Day 2007-01-10 21:49 ` J.A. Magallón 0 siblings, 2 replies; 12+ messages in thread From: linux-os (Dick Johnson) @ 2007-01-10 12:16 UTC (permalink / raw) To: Robert P. J. Day; +Cc: Stefan Richter, Linux kernel mailing list On Wed, 10 Jan 2007, Robert P. J. Day wrote: > On Tue, 9 Jan 2007, linux-os (Dick Johnson) wrote: > >> >> On Tue, 9 Jan 2007, Stefan Richter wrote: >> >>> Robert P. J. Day wrote: >>>> just to stir the pot a bit regarding the discussion of the two >>>> different ways to define macros, >>> >>> You mean function-like macros, right? >>> >>>> i've just noticed that the "({ })" >>>> notation is not universally acceptable. i've seen examples where >>>> using that notation causes gcc to produce: >>>> >>>> error: braced-group within expression allowed only inside a function >>> >>> And function calls and macros which expand to "do { expr; } while (0)" >>> won't work anywhere outside of functions either. >>> >>>> i wasn't aware that there were limits on this notation. can someone >>>> clarify this? under what circumstances *can't* you use that notation? >>>> thanks. >>> >>> The limitations are certainly highly compiler-specific. >> >> I don't think so. You certainly couldn't write working 'C' code like >> this: >> >> do { a = 1; } while(0); >> >> This _needs_ to be inside a function. In fact any runtime operations >> need to be inside functions. It's only in assembly that you could >> 'roll your own' code like: >> >> main: >> ret 0 >> >> >> Most of these errors come about as a result of changes where a macro >> used to define a constant. Later on, it was no longer a constant in >> code that didn't actually get compiled during the testing. > > just FYI, the reason i brought this up in the first place is that i > noticed that the ALIGN() macro in kernel.h didn't verify that the > alignment value was a power of 2, so i thought -- hmmm, i wonder if > there are any invocations where that's not true, so i (temporarily) > rewrote ALIGN to incorporate that check, and the build blew up > including include/net/neighbour.h, which contains the out-of-function > declaration: > > struct neighbour > { > ... > unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; > ... > > so it's not a big deal, it was just me goofing around and breaking > things. > > rday Hmmm, in that case you would be trying to put code inside a structure! Neat --if you could do it! Cheers, Dick Johnson Penguin : Linux version 2.6.16.24 on an i686 machine (5592.72 BogoMips). New book: http://www.AbominableFirebug.com/ _ \x1a\x04 **************************************************************** The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-10 12:16 ` linux-os (Dick Johnson) @ 2007-01-10 13:46 ` Robert P. J. Day 2007-01-10 14:07 ` linux-os (Dick Johnson) 2007-01-10 18:25 ` Stefan Richter 2007-01-10 21:49 ` J.A. Magallón 1 sibling, 2 replies; 12+ messages in thread From: Robert P. J. Day @ 2007-01-10 13:46 UTC (permalink / raw) To: linux-os (Dick Johnson); +Cc: Stefan Richter, Linux kernel mailing list On Wed, 10 Jan 2007, linux-os (Dick Johnson) wrote: > > On Wed, 10 Jan 2007, Robert P. J. Day wrote: > > just FYI, the reason i brought this up in the first place is that > > i noticed that the ALIGN() macro in kernel.h didn't verify that > > the alignment value was a power of 2, so i thought -- hmmm, i > > wonder if there are any invocations where that's not true, so i > > (temporarily) rewrote ALIGN to incorporate that check, and the > > build blew up including include/net/neighbour.h, which contains > > the out-of-function declaration: > > > > struct neighbour > > { > > ... > > unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; > > ... > > > > so it's not a big deal, it was just me goofing around and breaking > > things. > > > > rday > > > Hmmm, in that case you would be trying to put code inside a > structure! Neat --if you could do it! well, yes, but it does raise a potential issue. currently, that ALIGN() macro is being used to define one of the members of that structure. since it's a "simple" macro, there's no problem. but there are *plenty* of macros in the source tree that incorporate either the "do-while" or "({ })" notation. what the above implies is that the ALIGN() macro can *never* be extended in that way because of the way it's being used in the struct definition above, outside of a function. doesn't that place an unnecessarily limit on what might be done with ALIGN() in the future? because of how it's being used in that single structure definition, it is forever restricted from being extended. isn't that perhaps a dangerous restriction for any macro? rday ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-10 13:46 ` Robert P. J. Day @ 2007-01-10 14:07 ` linux-os (Dick Johnson) 2007-01-10 18:25 ` Stefan Richter 1 sibling, 0 replies; 12+ messages in thread From: linux-os (Dick Johnson) @ 2007-01-10 14:07 UTC (permalink / raw) To: Robert P. J. Day; +Cc: Stefan Richter, Linux kernel mailing list On Wed, 10 Jan 2007, Robert P. J. Day wrote: > On Wed, 10 Jan 2007, linux-os (Dick Johnson) wrote: > >> >> On Wed, 10 Jan 2007, Robert P. J. Day wrote: > >>> just FYI, the reason i brought this up in the first place is that >>> i noticed that the ALIGN() macro in kernel.h didn't verify that >>> the alignment value was a power of 2, so i thought -- hmmm, i >>> wonder if there are any invocations where that's not true, so i >>> (temporarily) rewrote ALIGN to incorporate that check, and the >>> build blew up including include/net/neighbour.h, which contains >>> the out-of-function declaration: >>> >>> struct neighbour >>> { >>> ... >>> unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; >>> ... >>> >>> so it's not a big deal, it was just me goofing around and breaking >>> things. >>> >>> rday >> >> >> Hmmm, in that case you would be trying to put code inside a >> structure! Neat --if you could do it! > > well, yes, but it does raise a potential issue. currently, that > ALIGN() macro is being used to define one of the members of that > structure. since it's a "simple" macro, there's no problem. > > but there are *plenty* of macros in the source tree that incorporate > either the "do-while" or "({ })" notation. what the above implies is > that the ALIGN() macro can *never* be extended in that way because of > the way it's being used in the struct definition above, outside of a > function. > > doesn't that place an unnecessarily limit on what might be done with > ALIGN() in the future? because of how it's being used in that single > structure definition, it is forever restricted from being extended. > isn't that perhaps a dangerous restriction for any macro? > > rday Remember that a macro simply substitutes "text." If the new text doesn't make any sense, the compiler will barf. There are gnu extensions such as __attribute__ that can be used to manipulate structure members in non-default ways. Also alignment only occurs when data-space in allocated either at runtime or at link time. This knowledge is useful when you are defining structures that will have elements accessed by pointers. You put the largest elements (a.k.a. sizeof()) at the beginning of the structure. Cheers, Dick Johnson Penguin : Linux version 2.6.16.24 on an i686 machine (5592.72 BogoMips). New book: http://www.AbominableFirebug.com/ _ \x1a\x04 **************************************************************** The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them. Thank you. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-10 13:46 ` Robert P. J. Day 2007-01-10 14:07 ` linux-os (Dick Johnson) @ 2007-01-10 18:25 ` Stefan Richter 1 sibling, 0 replies; 12+ messages in thread From: Stefan Richter @ 2007-01-10 18:25 UTC (permalink / raw) To: Robert P. J. Day; +Cc: linux-os (Dick Johnson), Linux kernel mailing list Robert P. J. Day wrote: [...] > what the above implies is > that the ALIGN() macro can *never* be extended in that way because of > the way it's being used in the struct definition above, outside of a > function. > > doesn't that place an unnecessarily limit on what might be done with > ALIGN() in the future? [...] The one occurrence which is different from others could be changed. But more importantly: Don't overuse macros. -- Stefan Richter -=====-=-=== ---= -=-=- http://arcgraph.de/sr/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-10 12:16 ` linux-os (Dick Johnson) 2007-01-10 13:46 ` Robert P. J. Day @ 2007-01-10 21:49 ` J.A. Magallón 2007-01-10 22:04 ` Andreas Schwab 1 sibling, 1 reply; 12+ messages in thread From: J.A. Magallón @ 2007-01-10 21:49 UTC (permalink / raw) To: linux-os (Dick Johnson) Cc: Robert P. J. Day, Stefan Richter, Linux kernel mailing list On Wed, 10 Jan 2007 07:16:55 -0500, "linux-os \(Dick Johnson\)" <linux-os@analogic.com> wrote: > > On Wed, 10 Jan 2007, Robert P. J. Day wrote: > > > On Tue, 9 Jan 2007, linux-os (Dick Johnson) wrote: > > > >> > >> On Tue, 9 Jan 2007, Stefan Richter wrote: > >> > >>> Robert P. J. Day wrote: > >>>> just to stir the pot a bit regarding the discussion of the two > >>>> different ways to define macros, > >>> > >>> You mean function-like macros, right? > >>> > >>>> i've just noticed that the "({ })" > >>>> notation is not universally acceptable. i've seen examples where > >>>> using that notation causes gcc to produce: > >>>> > >>>> error: braced-group within expression allowed only inside a function > >>> > >>> And function calls and macros which expand to "do { expr; } while (0)" > >>> won't work anywhere outside of functions either. > >>> > >>>> i wasn't aware that there were limits on this notation. can someone > >>>> clarify this? under what circumstances *can't* you use that notation? > >>>> thanks. > >>> > >>> The limitations are certainly highly compiler-specific. > >> > >> I don't think so. You certainly couldn't write working 'C' code like > >> this: > >> > >> do { a = 1; } while(0); > >> > >> This _needs_ to be inside a function. In fact any runtime operations > >> need to be inside functions. It's only in assembly that you could > >> 'roll your own' code like: > >> > >> main: > >> ret 0 > >> > >> > >> Most of these errors come about as a result of changes where a macro > >> used to define a constant. Later on, it was no longer a constant in > >> code that didn't actually get compiled during the testing. > > > > just FYI, the reason i brought this up in the first place is that i > > noticed that the ALIGN() macro in kernel.h didn't verify that the > > alignment value was a power of 2, so i thought -- hmmm, i wonder if > > there are any invocations where that's not true, so i (temporarily) > > rewrote ALIGN to incorporate that check, and the build blew up > > including include/net/neighbour.h, which contains the out-of-function > > declaration: > > > > struct neighbour > > { > > ... > > unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; > > ... > > > > so it's not a big deal, it was just me goofing around and breaking > > things. > > > > rday > > > Hmmm, in that case you would be trying to put code inside a structure! > Neat --if you could do it! > The ({ }) is a block expression, ie, it allows declaring variables and executing code. Its a gcc extension trying to resemble what other languages like ML have: ML: f = let y = x*x in 2*y + sin(y) end GNU C: f = ({ int y = x*x; 2*y + sin(y); }) So you can put it on every place you could also put a { } block or declare a variable. {} is a compund command and ({ }) is a compund expression (or block expression, do not know which is the good name in engelish). -- J.A. Magallon <jamagallon()ono!com> \ Software is like sex: \ It's better when it's free Mandriva Linux release 2007.1 (Cooker) for i586 Linux 2.6.19-jam03 (gcc 4.1.2 20061110 (prerelease) (4.1.2-0.20061110.1mdv2007.1)) #1 SMP PREEMPT ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: macros: "do-while" versus "({ })" and a compile-time error 2007-01-10 21:49 ` J.A. Magallón @ 2007-01-10 22:04 ` Andreas Schwab 0 siblings, 0 replies; 12+ messages in thread From: Andreas Schwab @ 2007-01-10 22:04 UTC (permalink / raw) To: J.A. Magallón Cc: linux-os (Dick Johnson), Robert P. J. Day, Stefan Richter, Linux kernel mailing list "J.A. Magallón" <jamagallon@ono.com> writes: > {} is a compund command and ({ }) is a compund expression > (or block expression, do not know which is the good name in engelish). gcc calls it a statement expression. Andreas. -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2007-01-10 22:04 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-08 18:50 macros: "do-while" versus "({ })" and a compile-time error Robert P. J. Day
2007-01-09 17:08 ` H. Peter Anvin
2007-01-09 17:33 ` Stefan Richter
2007-01-09 19:23 ` linux-os (Dick Johnson)
2007-01-09 20:19 ` Stefan Richter
2007-01-10 6:20 ` Robert P. J. Day
2007-01-10 12:16 ` linux-os (Dick Johnson)
2007-01-10 13:46 ` Robert P. J. Day
2007-01-10 14:07 ` linux-os (Dick Johnson)
2007-01-10 18:25 ` Stefan Richter
2007-01-10 21:49 ` J.A. Magallón
2007-01-10 22:04 ` Andreas Schwab
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox