473,320 Members | 1,828 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

is this valid c or a compiler bug?

Hi,

After a long debugging session I tracked down a
bug to the following line of code:

np = &nl[alloc_memory()]; /* nl & np are NODE * */

The problem is that nl is volatile--alloc_memory() may
change it (via realloc). The AIX compiler fails--it grabs
the value of nl before the call to alloc_memory(). The
Windows VC 6.0 compiler handles it correctly.

So is this a compiler bug, programmer error or ambiguous c?

Thanks,
Keith
Nov 14 '05 #1
6 1257
Keith Vetter <ke****@clover.net> scribbled the following:
Hi, After a long debugging session I tracked down a
bug to the following line of code: np = &nl[alloc_memory()]; /* nl & np are NODE * */ The problem is that nl is volatile--alloc_memory() may
change it (via realloc). The AIX compiler fails--it grabs
the value of nl before the call to alloc_memory(). The
Windows VC 6.0 compiler handles it correctly. So is this a compiler bug, programmer error or ambiguous c?


Ambiguous C. This is the same as np = &(*(nl + alloc_memory())), and
the order of evaluation of the + operator's operands is unspecified.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"The day Microsoft makes something that doesn't suck is probably the day they
start making vacuum cleaners."
- Ernst Jan Plugge
Nov 14 '05 #2
On 26 Feb 2004 12:25:38 -0800, ke****@clover.net (Keith Vetter) wrote:
Hi,

After a long debugging session I tracked down a
bug to the following line of code:

np = &nl[alloc_memory()]; /* nl & np are NODE * */
That would be rewritten by any compiler to:

np = & * (nl + alloc_memory());

There would be no obligation on the part of any compiler to evaluate nl
before alloc_memory() or vice-versa. Looks like UB if alloc_memory futzes
with nl.
-leor

The problem is that nl is volatile--alloc_memory() may
change it (via realloc). The AIX compiler fails--it grabs
the value of nl before the call to alloc_memory(). The
Windows VC 6.0 compiler handles it correctly.

So is this a compiler bug, programmer error or ambiguous c?

Thanks,
Keith


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #3
Leor Zolman <le**@bdsoft.com> wrote:
On 26 Feb 2004 12:25:38 -0800, ke****@clover.net (Keith Vetter) wrote:
After a long debugging session I tracked down a
bug to the following line of code:

np = &nl[alloc_memory()]; /* nl & np are NODE * */


That would be rewritten by any compiler to:

np = & * (nl + alloc_memory());

There would be no obligation on the part of any compiler to evaluate nl
before alloc_memory() or vice-versa. Looks like UB if alloc_memory futzes
with nl.


No, though I understand why you think so. But there's a sequence point
just before a function is called, and another just after any statement,
including alloc_memory()'s return statement. So regardless of whether nl
is read before or after alloc_memory() is called, there's always a
sequence point in between.
This makes the behaviour not-undefined; but because of the unspecified
order of the operands of + (or most other operators), it isn't _well_
defined, either; in fact, AFAICT the entire behaviour is unspecified, as
well. IOW, it must _either_ read nl and then update it inside
alloc_memory(), _or_ first update nl in the function and then read it;
it may not scribble over nl while it's still reading it, which would be
allowed with undefined behaviour.
All of this, of course, assumes that alloc_memory() _is_ a function, and
not a macro; if it's a macro, all bets are off, and you could easily
have undefined behaviour.

Richard
Nov 14 '05 #4
In <b8**************************@posting.google.com > ke****@clover.net (Keith Vetter) writes:
After a long debugging session I tracked down a
bug to the following line of code:

np = &nl[alloc_memory()]; /* nl & np are NODE * */

The problem is that nl is volatile--alloc_memory() may
change it (via realloc). The AIX compiler fails--it grabs
the value of nl before the call to alloc_memory(). The
Windows VC 6.0 compiler handles it correctly.

So is this a compiler bug, programmer error or ambiguous c?


Programmer error, if the function call was supposed to be evaluated
before nl. When the language doesn't specify an evaluation order
(and it seldom does), it is programmer's responsibility to enforce the
desired evaluation order, by decomposing the expression into
subexpressions:

tmp = alloc_memory();
np = nl + tmp;

Now, you are guaranteed that the alloc_memory function call will be
evaluated before nl, because the end of the first expression acts as a
sequence point.

The volatility of nl just doesn't make any difference to this discussion:
it means that nl *must* be evaluated (instead of reusing an old copy of
it that might still be available in a register), but the exact moment nl
is evaluated is still unspecified (both before and after the alloc_memory
function calls are valid options for the compiler).

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #5
On Fri, 27 Feb 2004 08:09:52 GMT, rl*@hoekstra-uitgeverij.nl (Richard Bos)
wrote:
Leor Zolman <le**@bdsoft.com> wrote:
On 26 Feb 2004 12:25:38 -0800, ke****@clover.net (Keith Vetter) wrote:
>After a long debugging session I tracked down a
>bug to the following line of code:
>
> np = &nl[alloc_memory()]; /* nl & np are NODE * */
That would be rewritten by any compiler to:

np = & * (nl + alloc_memory());

There would be no obligation on the part of any compiler to evaluate nl
before alloc_memory() or vice-versa. Looks like UB if alloc_memory futzes
with nl.


No, though I understand why you think so. But there's a sequence point
just before a function is called, and another just after any statement,
including alloc_memory()'s return statement. So regardless of whether nl
is read before or after alloc_memory() is called, there's always a
sequence point in between.
This makes the behaviour not-undefined; but because of the unspecified
order of the operands of + (or most other operators), it isn't _well_
defined, either; in fact, AFAICT the entire behaviour is unspecified, as
well. IOW, it must _either_ read nl and then update it inside
alloc_memory(), _or_ first update nl in the function and then read it;
it may not scribble over nl while it's still reading it, which would be
allowed with undefined behaviour.


Okay, I've finally gotten clear on what I was trying to say in the first
place. Turns out I /think/ I actually had "a right idea", but did an awful
job articulating it.

First of all, I agree 100% with everything you say about the sequence
points and order of evaluation of the operands to '+' contributing to
unspecified (rather than undefined) behavior in the (rewritten)
subexpression:

(nl + alloc_memory())

However, I maintain that there is still the /potential/ for undefined
behavior as soon as the + operator is applied, since the result of the
addition might be an invalid pointer (and most certainly /would/ be if nl
represents a "simple" dynamically allocated array, whose old memory was
just deleted during the alloc_memory() call, in the case where the compiler
evaluates nl before the call to the function.)

I'll admit I was originally thinking that the UB wouldn't kick in until the
application of the indirection operator, but now it seems that we've got
potential UB immediately upon conclusion of the addition, making the last
thing I said up above ("Looks like UB...") technically correct. Do I have
a leg to stand on?
-leor
All of this, of course, assumes that alloc_memory() _is_ a function, and
not a macro; if it's a macro, all bets are off, and you could easily
have undefined behaviour.

Richard


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
Nov 14 '05 #6
Leor Zolman <le**@bdsoft.com> wrote:
First of all, I agree 100% with everything you say about the sequence
points and order of evaluation of the operands to '+' contributing to
unspecified (rather than undefined) behavior in the (rewritten)
subexpression:

(nl + alloc_memory())

However, I maintain that there is still the /potential/ for undefined
behavior as soon as the + operator is applied, since the result of the
addition might be an invalid pointer


Ah, yes, of course! Hadn't thought of that. Yes, in that case, you would
certainly get UB.

Richard
Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Colin JN Breame | last post by:
Hi, I'm trying to figure out whether this way of passing arrays is valid. It seems to work however, I'm experiencing problems with another program that might be related. If this is not...
24
by: s.subbarayan | last post by:
Dear all, According to standards is this valid: char TmpPtrWriteBuffer; void* PtrWriteBuffer =(void*) TmpPtrWriteBuffer; I had a debate with my colleagues that anything cant be typecasted to...
20
by: Petter Reinholdtsen | last post by:
Is the code fragment 'char a = ("a");' valid ANSI C? The problematic part is '("a")'. I am sure 'char a = "a";' is valid ANSI C, but I am more unsure if it is allowed to place () around the...
5
by: Chris | last post by:
Hi all We have a strange problem with macros: #define SQLST_MAP_IND_O(Tbl,Fld) i##Tbl##_O=i##Tbl##_##Fld; SQLST_MAP_IND_I(RAGREEJ1,FORMFROMTMSTP); => gcc 3.3.4 gives the following error:...
4
by: Chris Croughton | last post by:
Does a translation unit have to have at least one externally visible declaration or function definition to be valid? As I read the standard, it doesn't: it must have at least one declaration or...
5
by: Sriram Rajagopalan | last post by:
Hi, Is the extra comma at the end of an enumerator-list valid according to the C standards? With the gcc compiler the following is valid: enum DAYS {MONDAY, TUESDAY, }day1; gcc does not...
13
by: joenuts | last post by:
Is it possible for a function to test one of it's passed in variables (reference to object) for validity? I would like the displayString( string &obString) function to verify that obString 1)...
21
by: Kannan | last post by:
Its been a while I have done pure C programming (I was coding in C++). Is the following function valid according to standard C? int main(int argc, char *argv) { int x; x = 9; printf("Value...
2
by: anon.asdf | last post by:
Hello! 1) =============================== When trying to define an array of std::string ... func( (std::string ) { std::string("ab"), std::string("cd"), std::string("ef") } , 3 ); ...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.