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

Sequence point violation?


I'm writing a program currently that was working perfectly until I
decided to compile it with "-O3" in gcc (-O3 specifies optimisation of
the third level).

Anyway, I found the problem. I had the following function:

void StrToLower(char *p)
{
while ( *p++ = tolower( (char unsigned)*p ) );
}

I changed it to the following and now it works properly:

void StrToLower(char *p)
{
for ( ; *p = tolower((char unsigned)*p); ++p);
}

I'm not entirely convinced however that there's a sequence point
violation in the following:

*p++ = tolower( (char unsigned)*p );

Any thoughts? There should be a sequence point at tolower's evaluation of
its arguments... right?

--
Tomás Ó hÉilidhe
Jan 2 '08 #1
4 2504
"Tomás Ó hÉilidhe" <to*@lavabit.comwrites:
Anyway, I found the problem. I had the following function:

void StrToLower(char *p)
{
while ( *p++ = tolower( (char unsigned)*p ) );
}
[...]
Any thoughts? There should be a sequence point at tolower's evaluation of
its arguments... right?
Yes. However, the compiler is not obligated to evaluate the
right side of the assignment before the left side. It can
evaluate *p++ and (char unsigned)*p together. Hence, the
problem.
--
"...Almost makes you wonder why Heisenberg didn't include postinc/dec operators
in the uncertainty principle. Which of course makes the above equivalent to
Schrodinger's pointer..."
--Anthony McDonald
Jan 2 '08 #2
In article <Xn***************************@194.125.133.14>,
Tomás Ó hÉilidhe <to*@lavabit.comwrote:
while ( *p++ = tolower( (char unsigned)*p ) );
[vs]
for ( ; *p = tolower((char unsigned)*p); ++p);
The former is "wrong" (invalid C code) and the latter is right,
because:
>I'm not entirely convinced however that there's a sequence point
violation in the following:

*p++ = tolower( (char unsigned)*p );

Any thoughts? There should be a sequence point at tolower's evaluation of
its arguments... right?
There is indeed a sequence point before a call. (I forget whether
C99 fixed the "loophole" in C89, where functions described in the
standard could be macros, and thus sidestep the sequence-point
requirements for function calls, but for the moment we may as well
assume tolower() really is a function-call.)

The problem is, the left-hand side (LHS) of the assignment operator
has no sequencing constraints with respect to the right-hand side
(RHS). So, although there is a sequence point before the call to
tolower(), the "for-its-address" ("lvalue") evaluation of *p++ on
the LHS could be not-at-all, partly, or completely evaluated at
the time the RHS evaluation begins. The use of *p on the right
then conflicts with the update of p in *p++ on the left. This
renders the behavior undefined.

If the behavior were not undefined already, then we might have to
start worrying about whether tolower() is a macro instead of a
function, and whether C99 has fixed the loophole. But the
corrected version is safe -- although I would probably write
it as:

while ((*p = tolower((unsigned char)*p)) != '\0')
p++;

myself (because I dislike empty loops, as they often need extra
checking to make sure they are not simply typographic errors in
the code).
--
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.
Jan 2 '08 #3
Ben Pfaff wrote, On 02/01/08 17:48:
"Tomás Ó hÉilidhe" <to*@lavabit.comwrites:
>Anyway, I found the problem. I had the following function:

void StrToLower(char *p)
{
while ( *p++ = tolower( (char unsigned)*p ) );
}

[...]
>Any thoughts? There should be a sequence point at tolower's evaluation of
its arguments... right?

Yes. However, the compiler is not obligated to evaluate the
right side of the assignment before the left side. It can
evaluate *p++ and (char unsigned)*p together. Hence, the
problem.
I.e. there is no sequence point between evaluating the p on the right
and the p++ on the left. So p is modified (by the p++) and read for a
purpose other than calculating the new value of p (as opposed to *p) and
that invokes undefined behaviour.

Tomás should think himself lucky that the problem showed up at -O3
rather than lurking hidden until demonstrating it to a big customer.
--
Flash Gordon
Jan 2 '08 #4
On Wed, 02 Jan 2008 19:24:29 +0000, Chris Torek wrote:
There is indeed a sequence point before a call. (I forget whether C99
fixed the "loophole" in C89, where functions described in the standard
could be macros, and thus sidestep the sequence-point requirements for
function calls, but for the moment we may as well assume tolower()
really is a function-call.)
I wouldn't consider it a loophole. C99 mentions the fact that macro
definitions for standard library functions don't have the same sequence
point requirements as the function in a footnote.
Jan 2 '08 #5

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

Similar topics

3
by: Matjaz | last post by:
Dear all, I have run into a problem using python lists and sequence protocol. The first code snippet uses explicit list operations and works fine. PyObject *argseq, *ov; int i, v, len; ...
3
by: Sensorflo | last post by:
After browsing though many newsgroups articels I'm still not shure how operator precedence, operator associativity, sequence points, side effects go together. Currently I have the following view: ...
3
by: sugaray | last post by:
Can somebody explain to me what is sequence point ? With few examples would be even better. Thanx for your help.
53
by: Deniz Bahar | last post by:
I know the basic definition of a sequence point (point where all side effects guaranteed to be finished), but I am confused about this statement: "Between the previous and next sequence point an...
7
by: akarl | last post by:
Hi all, Why do I get a warning from gcc with the following program? $ cat test.c #include <stdio.h> int f(int n) { return n;
4
by: Eric E | last post by:
Hi, I have a question about sequences. I need a field to have values with no holes in the sequence. However, the values do not need to be in order. My users will draw a number or numbers from...
7
by: Kenneth Brody | last post by:
(From something brought up on "Help with array/pointer segmentation fault needed" thread.) Is "?" a sequence point? Or, more directly, is the following defined? /* Will "ptr" be guaranteed...
9
by: John Smith | last post by:
I've been playing with splint, which returns the following warning for the code below: statlib.c: (in function log_norm_pdf) statlib.c(1054,31): Expression has undefined behavior (left operand...
2
by: Eric Lilja | last post by:
I'm looking at an assignment where the students are expected to write a class with a given purpose. According to the assignment, you should be able to do this with instances of the class:...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
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
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.