473,406 Members | 2,356 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,406 software developers and data experts.

dereferencing type-punned pointer will break strict-aliasing rules

I have a program for which this line:

if(! lstrtol(&atoken[2],length-2,(long *) &(lclparams->pad)) ||
(lclparams->pad< 0)){

generates the warning below, but ONLY if the gcc compiler is at -O2 or
-O3. I don't see any reason why optimization should change things much
in this piece of code - there's no way to optimize it out and I have
verified that this particular line does what it should no matter how the
program is compiled. Anyway, this is the warning:

warning: dereferencing type-punned pointer will break
strict-aliasing rules

The function lstrtol has this prototype:

int lstrtol(char *string,int length, long *ival);

and the pad field in lclparams in an int.

So two questions:

1. What doesn't the compiler like? Is it the cast of (long *) for
&(int_storage)?
2. Any ideas why the compiler only flags this when it's optimizing?
Seems like whatever the issue is it shouldn't have anything to do
with optimization levels.

I know that using a scratch long variable to retrieve the value
and then copying that into the int field eliminates the warning,
and it won't overflow as the values are going to be small integers, but
I am curious why the compiler acts this way.

Thanks,

David Mathog

Jul 3 '07 #1
3 29664
On Jul 3, 5:01 pm, David Mathog <mat...@caltech.eduwrote:
I have a program for which this line:

if(! lstrtol(&atoken[2],length-2,(long *) &(lclparams->pad)) ||
(lclparams->pad< 0)){

generates the warning below, but ONLY if the gcc compiler is at -O2 or
-O3. I don't see any reason why optimization should change things much
in this piece of code - there's no way to optimize it out and I have
verified that this particular line does what it should no matter how the
program is compiled. Anyway, this is the warning:

warning: dereferencing type-punned pointer will break
strict-aliasing rules

The function lstrtol has this prototype:

int lstrtol(char *string,int length, long *ival);

and the pad field in lclparams in an int.

So two questions:

1. What doesn't the compiler like? Is it the cast of (long *) for
&(int_storage)?
Yes.
2. Any ideas why the compiler only flags this when it's optimizing?
Seems like whatever the issue is it shouldn't have anything to do
with optimization levels.
The example breaks the aliasing rules and hence invokes undefined
behavior so anything is allowed including working properly in one case
and giving you a diagnostic in another. The point of the aliasing
rules is to allow the compiler to perform certain optimizations by
assuming that a variable of type A won't be accessed through a pointer
to type B. You are accessing a variable of type int through a pointer
to an incompatible type which probably isn't an issue on your
implementation unless the compiler is performing these optimizations
hence the warning appears only in this case.

Robert Gamble

Jul 3 '07 #2
On Tue, 03 Jul 2007 14:01:44 -0700, David Mathog <ma****@caltech.edu>
wrote:
>I have a program for which this line:

if(! lstrtol(&atoken[2],length-2,(long *) &(lclparams->pad)) ||
(lclparams->pad< 0)){

generates the warning below, but ONLY if the gcc compiler is at -O2 or
-O3. I don't see any reason why optimization should change things much
in this piece of code - there's no way to optimize it out and I have
verified that this particular line does what it should no matter how the
program is compiled. Anyway, this is the warning:

warning: dereferencing type-punned pointer will break
strict-aliasing rules

The function lstrtol has this prototype:

int lstrtol(char *string,int length, long *ival);

and the pad field in lclparams in an int.
Since pad is an int, it is possible that it is not aligned properly
for a long. If that happens to be the case, then casting it's address
to type long* invokes undefined behavior.

Furthermore, since you passing a long* to the function, it is
reasonable that the function would use this to store a long value in
the memory pointed to. If your function in fact does this and if
sizeof(long)!=sizeof(int), you have undefined behavior because the
function is storing the wrong number of bytes at the address.
Remove del for email
Jul 4 '07 #3
(Others have already answered pointing out other problems.)

In article <f6**********@naig.caltech.edu>
David Mathog <ma****@caltech.eduwrote:
[casting &intvar to (long *) produces the message:

warning: dereferencing type-punned pointer will break strict-aliasing rules

]
>but ONLY if the gcc compiler is at -O2 or -O3. I don't see any
reason why optimization should change things much in this piece
of code ...
Optimizers love to make assumptions. The assumptions they are
allowed to make are those defined by the language [%]. In this
case, at "higher" optimization levels, gcc wants to make use of
the rule that any lvalue can only be accessed by:

- its name, or
- a pointer that points to its type, or
- a pointer that points to "individual bytes" (e.g., char *).

In particular, for instance, suppose we have the following code
fragment:

float x;
int *p;

if (sizeof(int) != sizeof(float)) {
printf("this program assumes sizeof(int) == sizeof(float)\n");
exit(EXIT_FAILURE);
}

p = (int *)&x;
x = 42.0;

<do lots of work with x that leaves it nonzero>

*p = 0;
if (x == 0.0)
printf("integer zero seems to be floating point zero too\n");
else
printf("verrry interesting! x = %g\n", x);

Now, on some machines (like the x86 for instance), it is very
helpful, for speed reasons, to keep "x" in something other than
ordinary RAM. If x can live in the FPU stack, for instance, the
compiler can use shorter and faster instructions to work with it
(in the <do lots of worksection).

But if the compiler *does* do this, then "p" points only to the
"ordinary RAM copy of x" (as opposed to the "live, useful copy of
x" inside the FPU stack). Changing *p changes only the non-live,
non-useful copy of x. When examining x after assigning to *p, the
compiler should use the live copy of x (in the FPU stack), which
-- assuming the <do lots of worksection really does leave x
nonzero -- will not be equal to 0.0, and the code fragment will
claim that the x86 makes all-zero-bits a non-zero floating point
number (which is in fact false).

The compiler is certainly *allowed* to do this, because modifying
an int (*p) is not supposed to change a float (x).

GCC's complaint:
warning: dereferencing type-punned pointer will break
strict-aliasing rules
is supposed to come out in those cases where it can detect, at
compile time, that some sort of source-level chicanery (such as
the above) could cause later optimization passes to make assumptions
that, while allowed by the Standard, will surprise some programmers.
The detector is probably imperfect, and is clearly only run at
higher optimization levels. (This is true of many of gcc's useful
warnings. In at least some cases, this is because the data structures
that allow the compiler to detect the problem it will warn about are
only built during optimization.)

[% In some cases, compilers may have extra optimization flags that
allow them to make assumptions *not* guaranteed by the language.
In other words, the programmer can, on the compilation flags line,
"write checks that the language can't cash", to borrow a phrase.
If you are such a programmer, make sure your code, at least, *can*
cash them. :-) ]
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 5 '07 #4

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

Similar topics

8
by: Jan Decaluwe | last post by:
Is there a way to dereference a cell object (that is, get the object that it references to) in Python? Regards, Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan...
2
by: Matthias Kaeppler | last post by:
Hello, I was wondering, does dereferencing past-the-end iterators yield undefined behavior? Especially, is the result of calling an STL algorithm on an empty range undefined? For example...
11
by: jlara | last post by:
Working on an embedded controller, I generally find it convenient to define the following de-referenced pointer: #define portb (*(unsigned char *)(0x03u)) This enable me to write to a port as...
4
by: Max Sandman | last post by:
Say I've got a control c = textBox1 and a string that is a property of c, say string s = "Text". Is there a way in C# to use c and s to get the contents of textbox1.Text? sandman *** Sent...
16
by: Michael Maes | last post by:
Hi, How would I handle Dereferencing in vb.Net 2003. Something like: Dim txt As TextBox = DirectCast("txt" & someStringVariable, TextBox) This sadly won't work because a type of string...
0
by: Chris Fink | last post by:
When I am consuming a webservice, an object has an undefined value (inq3Type.Call3Data). I do not completely understand why this is happening and apologize for the vague question. My assumption...
28
by: Martin Jørgensen | last post by:
Hi, I have a "funny" question, which I think is pretty "healthy" to examine... This program is being investigated: - - - - - - - #include <iostream> using namespace std; #define DAYS 7
4
by: Tristan | last post by:
Hi all, I'm teaching myself C++ from C++ Primer 4th Ed., but I've not done any programming before and the damn thing has no answers in it! If I pass a reference to cin to a function called...
4
by: Caudata | last post by:
I am by no means an experienced c++ programmer, but I am trying to use a vector of vectors because it is convenient to store some strings while parsing a text file. I am having trouble with the...
5
by: sebastian | last post by:
I have a dereferencing template that I believe to be implemented correctly and complete, but I would like to have it checked for correctness to be sure. is this the right forum for such a thing?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.