473,748 Members | 8,530 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

the 'standard' is so strange

This behavior seems very strange to me, but I imagine that someone will
be able to 'explain' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void)
{
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );
putchar('\n');
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p2, *p2++);
}

-------------------- output -----------------------------------

0 a a
1 b b
2 c c
3 d d

0 b a
1 c b
2 d c
3 d

-------------------------------------------------------------

--
I understand you come from England,
but I promise not to hold it against
you.
Nov 17 '08 #1
20 2233
Pilcrow wrote:
printf("%d %c %c\n", i, *p1++, *p1 );
That line of code makes your program be undefined.

You modify p1 and read it twice
without an intervening sequence point,
to get an address of an object
that will have its value printed.
printf("%d %c %c\n", i, *p2, *p2++);
That one too.

N869
6.5 Expressions

[#2] Between the previous and next sequence point an object
shall have its stored value modified at most once by the
evaluation of an expression. Furthermore, the prior value
shall be accessed only to determine the value to be
stored.

--
pete
Nov 17 '08 #2
Pilcrow <Pi******@gmail .comwrites:
This behavior seems very strange to me, but I imagine that someone will
be able to 'explain' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void)
{
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );
It is not specified when the effect "p1++" will happen. Therefore
"*p1" is meaningless in this context. The compiler can do what it
likes.
putchar('\n');
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p2, *p2++);
Again, it is not specified when the effect "p2++" will happen. Likewise,
"*p2" is meaningless in this context. Again, the compiler can do what it
likes.
}

-------------------- output -----------------------------------

0 a a
1 b b
2 c c
3 d d
It appears that the compiler chose to evaluate the arguments to printf
from the right to the left, or to not perform the incrementation of p1
until after all arguments were evaluated. You were lucky, much worse
things could have happened.
0 b a
1 c b
2 d c
3 d
It appears that the compiler chose to evaluate the arguments to printf
from the right to the left, and to perform the incrementation of p2 in
the rightmost argument before proceeding to evaluate the argument to the
left of it. Again, you were lucky, much worse things could have happened.

Combining those two data points, I think we can concluded that the
compiler choses to evaluate its arguments from right to left and to
perform the side-effects associated with each argument as it processes
that argument. It is permitted to so do. It it not oblided to so do.

The compiler's behaviour does not in any way seem "very strange", it
simply appears undefined. The only strange behaviour is that of the
author of the code thinking he could get away with writing code with
undefined behaviour.

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.
Nov 17 '08 #3
Pilcrow <Pi******@gmail .comwrites:
This behavior seems very strange to me, but I imagine that someone will
be able to 'explain' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void)
{
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );
putchar('\n');
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p2, *p2++);
}

-------------------- output -----------------------------------

0 a a
1 b b
2 c c
3 d d

0 b a
1 c b
2 d c
3 d

-------------------------------------------------------------
Others have done a very good job of answering your question. But I'm
curious: why do you have such a dismissive attitude regarding the C
standard (putting the words "standard" and "explain" in quotation
marks and so forth)?

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 17 '08 #4
On Mon, 17 Nov 2008 09:18:44 -0800, Keith Thompson <ks***@mib.or g>
wrote:
>Pilcrow <Pi******@gmail .comwrites:
>This behavior seems very strange to me, but I imagine that someone will
be able to 'explain' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void)
{
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );
putchar('\n');
for(i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p2, *p2++);
}

-------------------- output -----------------------------------

0 a a
1 b b
2 c c
3 d d

0 b a
1 c b
2 d c
3 d

-------------------------------------------------------------

Others have done a very good job of answering your question. But I'm
curious: why do you have such a dismissive attitude regarding the C
standard (putting the words "standard" and "explain" in quotation
marks and so forth)?
Before posting my example I had already realised that I was not allowed
(at least in *this* case) to use a shortcut to modify an argument to a
function *within* the parens. I just assumed that the much-cited k&r
had fully defined the language. All these 'undefines' have me feeling
like I'm trying to herd cats. (snakes?)

To mix metaphores: just when I think I'm beginning to get a grip on C,
it turns into sea, and runs through my fingers.
Now I realise that I will have to read the 'standard', which seems to
have been written by a team composed of Philidelphia lawyers and
abstract mathematicians, neither of whom heard of Henry W Fowler. Truly
gelatinous prose. Technical writing need not be so murky. Oh, well, we
live to learn.

Maybe I'll try to make a catalog of *all* the 'undefines' and similar
gotchas in C. Written in English.

Thanks to all for a most illuminating experience.

BTW, what's a 'sequence point', and how could I recognize one in a dark
alley? Never mind, maybe the *standard* will tell me.

It's been real

--
I understand you come from England,
but I promise not to hold it against
you.
Nov 17 '08 #5
In article <ln************ @nuthaus.mib.or g>,
Keith Thompson <ks***@mib.orgw rote a bunch of crap, leading up to:
....
>
Maybe ``you'' should "read" the 'standard' before you *complain* about
/it/.
You are such a tool.

Nov 17 '08 #6
Pilcrow wrote:
....
Before posting my example I had already realised that I was not allowed
(at least in *this* case) to use a shortcut to modify an argument to a
function *within* the parens. I just assumed that the much-cited k&r
had fully defined the language. All these 'undefines' have me feeling
like I'm trying to herd cats. (snakes?)
K&R did not fully define the language. The C89 standard did define it,
but that definition included specifying, with considerable precision,
situations in which the standard does not specify the behavior.
Now I realise that I will have to read the 'standard', which seems to
have been written by a team composed of Philidelphia lawyers and
abstract mathematicians, neither of whom heard of Henry W Fowler. Truly
gelatinous prose. Technical writing need not be so murky. Oh, well, we
live to learn.
A key thing that you need to understand is that the standard is,
conceptually, a contract between implementors of C and developers of C
programs. If a developer writes strictly conforming code, a conforming
implementation has to produce exactly the behavior specified by the
standard. The "undefined behavior" that bothers you so much is simply
one of the several methods which the standard uses to identify code
which doesn't meet the contract requirements.

These ways are:
1. The standard requires that a conforming implementation must produce
at least one diagnostic message whenever given a program that contains
any syntax errors or constraint violations. An implementation is also
free to produce diagnostic messages for any other reason that it
wishes. Diagnostics are not required to provide you with any useful
information; they are not even required to be in any language that
anyone knows how to read. However, an implementation is required to
document how to identify diagnostic messages. If you don't find the
messages helpful, that's a legitimate issue to complain about to the
implementor - but it doesn't make the implementation non-conforming.

Having generated that diagnostic, an implementation is free to process
your code a produce a program that you might or might not be willing
to actually execute (I wouldn't).

2. Unspecified behavior: in some cases, the standard allows an
implementation a range of choices. This is usually not done just for
the fun of it - it's done because existing implementations handle the
situation in different ways, often because the best way to handle the
situation is different on different machines. By making the behavior
unspecified, the standard makes it easier to implement C in an
efficient fashion on a much wider variety of platforms than just about
any other language. The price we pay for this is that we have to be
careful to avoid writing code that depends upon unspecified behavior,
unless we have a very good reason to tie a program to a particular
implementation of C.

A program whose behavior is unspecified must still behave in one of
permitted ways, an implementation is not free to make it behave in a
completely arbitrary fashion. In many cases, unspecified behavior is
also implementation-defined behavior; in that case, the implementation
is required to document which choice it made. See Annex J.3 for
implementation-defined behavior; see Annex J.1 for other unspecified
behavior.

3. Undefined behavior: the standard imposes no requirements, of any
kind, on the behavior. An implementation is free to provide it's own
definition of the behavior. If you're deliberately relying upon a
particular implementation' s definition of the behavior, that's fine.
However, if you intend your code to be portable, you must avoid
undefined behavior completely. See Annex J.2 for undefined behavior.
Maybe I'll try to make a catalog of *all* the 'undefines' and similar
gotchas in C. Written in English.
Virtually every sentence of the standard contains a "gotcha", many of
them contain several "gotchas". To write them out in clear English,
avoiding the technical jargon that makes the standard so difficult to
read, a complete list of the "gotchas" will have to be several times
longer than the standard itself.

....
BTW, what's a 'sequence point', and how could I recognize one in a dark
alley? Never mind, maybe the *standard* will tell me.
Here's the complete list of sequence points from Annex C:
— The call to a function, after the arguments have been evaluated (6.5.2.2).
— The end of the first operand of the following operators: logical AND && (6.5.13);
logical OR || (6.5.14); conditional ? (6.5.15); comma , (6.5.17).
— The end of a full declarator: declarators (6.7.5);
— The end of a full expression: an initializer (6.7.8); the expression in an expression
statement (6.8.3); the controlling expression of a selection statement (if or switch)
(6.8.4); the controlling expression of a while or do statement (6.8.5); each of the
expressions of a for statement (6.8.5.3); the expression in a return statement
(6.8.6.4).
— Immediately before a library function returns (7.1.4).
— After the actions associated with each formatted input/output function conversion
specifier (7.19.6, 7.24.2).
— Immediately before and immediately after each call to a comparison function, and
also between any call to a comparison function and any movement of the objects
passed as arguments to that call (7.20.5).
Nov 17 '08 #7
Pilcrow wrote:
>
This behavior seems very strange to me, but I imagine that someone
will be able to 'explain' it in terms of the famous C standard.

-------------------- code -----------------------------------
#include <stdio.h>

int main (void) {
char xx[]="abcd";
char * p1 = xx;
char * p2 = xx;
int i;
for (i = 0; i < 4; i++)
printf("%d %c %c\n", i, *p1++, *p1 );
From this point on your code is undefined. You have raised
undefined performance here. The compiler is entitled to do
whatever it wishes. Look up sequence points, and restrictions on
code between them.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.
Nov 17 '08 #8
Pilcrow wrote:
On Mon, 17 Nov 2008 09:18:44 -0800, Keith Thompson <ks***@mib.or g>
wrote:
>Others have done a very good job of answering your question. But I'm
curious: why do you have such a dismissive attitude regarding the C
standard (putting the words "standard" and "explain" in quotation
marks and so forth)?

Before posting my example I had already realised that I was not allowed
(at least in *this* case) to use a shortcut to modify an argument to a
function *within* the parens. I just assumed that the much-cited k&r
had fully defined the language. All these 'undefines' have me feeling
like I'm trying to herd cats. (snakes?)

To mix metaphores: just when I think I'm beginning to get a grip on C,
it turns into sea, and runs through my fingers.
C is indeed less well-defined than most other languages. The reason is
that C evolved and branched on its own long before the standards bodies
got their hands on it, and different implementors had wildly different
ideas about what different things meant. As a result, ANSI (and thus
ISO) was reduced to trying to document the areas where most or all of
them agreed and leaving the areas of disagreement undefined.

Also, C was always intended to be as efficient as possible, and what
behavior is most efficient on different systems varies. Finally, one of
C's greatest strengths is the ability to write both portable code (such
as cross-platform applications) and unportable code (such as device
drivers) in the same language; the way this is done is by allowing
"undefined" and "implementa tion-defined" behavior, which can be avoided
by anyone trying to write portable code but embraced by those who don't
care about portability.
Now I realise that I will have to read the 'standard', which seems to
have been written by a team composed of Philidelphia lawyers and
abstract mathematicians, neither of whom heard of Henry W Fowler. Truly
gelatinous prose. Technical writing need not be so murky. Oh, well, we
live to learn.

Maybe I'll try to make a catalog of *all* the 'undefines' and similar
gotchas in C. Written in English.
Start by translating Annex J, but I bet you'll find that your
translation is several times as long, and by the time you're complete,
you won't need it anymore because the Standard will have started to make
an odd sort of sense to you.
Thanks to all for a most illuminating experience.

BTW, what's a 'sequence point', and how could I recognize one in a dark
alley? Never mind, maybe the *standard* will tell me.
The most obvious sequence points are ;'s after expressions and function
calls. There are a few others, as noted in the Standard, but if you're
just getting started, the simplest approach is to assume for now that no
others exist. More important is why you need to _care_ about sequence
points, and I can't even begin to explain that in English...

S
Nov 17 '08 #9
Pilcrow wrote:
Keith Thompson <ks***@mib.orgw rote:
.... snip ...
>
>Take a look at Annex J of the C99 standard (or n1256 if you
don't have the official standard).

Turns out I have n1256. I thought that was it. Where can I get
the C99, and the other, previous ones? URL, please?
n1256 is more accurate than the printed versions you can buy.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home .att.net>
Try the download section.
Nov 18 '08 #10

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

Similar topics

16
1949
by: Pjer Holton | last post by:
If I were to build a Windows application that is a true standard Windows application in every conceivable way and that adheres to the MS Windows standards as much as possible (installation, GUI, printing, registry, RTF etc.), and if portability to other platforms is only a minor concern, ... would Python be a good choice? What packages, libraries and modules would you recommend for GUI, installation, data storage etc.? Thank you very...
25
3354
by: BJörn Lindqvist | last post by:
See: http://www.wxpython.org/quotes.php. especially: "wxPython is the best and most mature cross-platform GUI toolkit, given a number of constraints. The only reason wxPython isn't the standard Python GUI toolkit is that Tkinter was there first." - Guido van Rossum Guess, that answers my question, but isn't "Tkinter was there first" a very bad answer? :) It is kinda ugly too, so I wonder why it can't be replaced? Or maybe another GUI...
0
2163
by: Hugo Fjelsted Alrøe | last post by:
I am fairly new at MySQL, so please excuse any ignorance. We are using MySQL (version 3.23.48) in connection with an Eprints = archive. We have non-english deposits in the archive, and non-standard = characters are not always shown right in our system. They are shown = wrong in the subscription alerts that the archive generates and sends = out - this is what annoys us. And they are shown wrong in the database = itself. But they are shown...
8
2921
by: Sensei | last post by:
I have a quick question about the math library included in the standard C90 (and 99). The gcc, xlc and possibly other compilers/linkers on some unix platforms cannot use any math functions in math.h if a switch (-lm) is used, so *explicitly* having the linker use a file called libm.so or libm.a/dylib/whatever. Is it true on all the platforms? (answer: probably no)
52
3779
by: lovecreatesbeauty | last post by:
Why the C standard committee doesn't provide a standard implementation including the C compiler and library when the language standard document is published? C works on the abstract model of low level machine. C stands for portability and platform and machine independent. If the C compiler and C standard library are written in C itself, is it possible that one "standard" C compiler plus library is enough? The standard implementation is...
132
4635
by: Frederick Gotham | last post by:
If we look at a programming language such as C++: When an updated Standard comes out, everyone adopts it and abandons the previous one. It seems though that things aren't so clear-cut in the C community. It would seem that C99 is the most up-to-date Standard, but far more people seem to be working off the C89 Standard. Could someone please explain to me why this is so? --
21
2836
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 of x is: %d\n", x);
26
3821
by: Rick | last post by:
I'm told that "#pragma once" has made it into the ISO standard for either C or C++. I can't find any reference to that anywhere. If it's true, do any of you have a reference I can use? Thanks...
130
6785
by: euler70 | last post by:
char and unsigned char have specific purposes: char is useful for representing characters of the basic execution character set and unsigned char is useful for representing the values of individual bytes. The remainder of the standard integer types are general purpose. Their only requirement is to satisfy a minimum range of values, and also int "has the natural size suggested by the architecture of the execution environment". What are the...
0
8989
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9537
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9319
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8241
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6073
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4599
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3309
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2780
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2213
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.