|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hi,
I ran the program below. It should print out 2 but actually it prints out 1. What's going on? Should I report a bug against the compiler? Thanks. void main() { int a=1; a=a++; printf("%d", a); } |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Port Pirie wrote:
> Hi, > > I ran the program below. It should print out 2 but actually it prints > out 1. What's going on? Should I report a bug against the compiler? > > Thanks. > > > void main() > { > int a=1; > a=a++; > printf("%d", a); > } You have invoked undefined behaviour thrice. Firstly void main is not the proper prototype. Proper forms are int main(void) or int main(int, char**). Secondly you access an object to modify it's value twice within a sequence point. Thirdly you are calling a variadic function with no prototype in scope. Please read the FAQ at the following link: <http://www.c-faq.com/> <http://www.clc-wiki.net/> |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
In article <fkqn1v$cgq$1@aioe.org> Port Pirie <noone@nospam.invalid> wrote:
>I ran the program below. It should print out 2 but actually it prints >out 1. What's going on? Should I report a bug against the compiler? > >void main() >{ > int a=1; > a=a++; > printf("%d", a); >} You have asked a variant of Frequently Asked Questions 3.1, 3.2, and 3.3. See <http://c-faq.com/expr/index.html>. See also questions 11.12a through 11.15 at <http://c-faq.com/ansi/index.html>. -- 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. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
"santosh" <santosh.k83@gmail.com> schrieb im Newsbeitrag
news:fkqnl6$pn7$1@registered.motzarella.org... > Port Pirie wrote: > >> Hi, >> >> I ran the program below. It should print out 2 but actually it prints >> out 1. What's going on? Should I report a bug against the compiler? >> >> Thanks. >> >> >> void main() >> { >> int a=1; >> a=a++; >> printf("%d", a); >> } > > You have invoked undefined behaviour thrice. Four times actually > Firstly void main is not > the proper prototype. Proper forms are int main(void) or int main(int, > char**). Secondly you access an object to modify it's value twice > within a sequence point. Thirdly you are calling a variadic function > with no prototype in scope. and fourth you don't end your output with a \n bye, Jojo |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Dec 25, 12:46 pm, Port Pirie <no...@nospam.invalid> wrote:
> Hi, > > I ran the program below. It should print out 2 but actually it prints > out 1. What's going on? Should I report a bug against the compiler? > > Thanks. > > void main() > { > int a=1; > a=a++; > printf("%d", a); > > } The key point to your answer is the line: a=a++; it evaluates a to 1 in right side, assigns 1 to a in left side, then increments a used in right side. Use prefix increment instead, like this: a = ++a; Of course, it's advisable you take into account all other advises about prototype of main() and enting output with \n. ![]() |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Tue, 25 Dec 2007 14:07:58 +0100, Joachim Schmitz wrote:
> "santosh" <santosh.k83@gmail.com> schrieb im Newsbeitrag >> [...] >> You have invoked undefined behaviour thrice. > Four times actually > [...] > and fourth you don't end your output with a \n Whether that is required is implementation-defined. When it's not required, and your program don't provide one, your program is slightly less portable, but still has defined behaviour. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Tue, 25 Dec 2007 05:23:40 -0800, NicoleaSW wrote:
> The key point to your answer is the line: a=a++; > > it evaluates a to 1 in right side, assigns 1 to a in left side, then > increments a used in right side. Use prefix increment instead, like > this: > > a = ++a; This is exactly as broken as the original code. If you want to increment a, write a++, or ++a, or a += 1, or a = a + 1, or any other alternative that you can think of that updates a _once_. Even if it were valid C, there is no point in saying you want to update a, and then store the result in a. Updating a already stores the result in a. Trying to store it again makes no sense. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
Port Pirie wrote:
> Hi, > > I ran the program below. It should print out 2 but actually it prints > out 1. What's going on? Should I report a bug against the compiler? Your code (below) contains at least three errors (four under the old C89 standard). It cannot reasonably be expected to have any particular behavior. However, if you wanted to guess what the behavior might be of this incredibly error-laden code, consider this code block: { int a = 1; int c; c = a++; /* a++ has the value 1, that value is assigned to c */ } Does that give you a hint? If you do not understand why a++ has the value 1, open any elementary C text and read the very first page in which the post-increment operator ++ is introduced. > void main() > { > int a=1; > a=a++; > printf("%d", a); > } |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
NicoleaSW@gmail.com wrote:
> The key point to your answer is the line: > a=a++; > > it evaluates a to 1 in right side, assigns 1 to a in left side, then > increments a used in right side. You might think so, but you would be horribly wrong. This line has completely undefinied behavior. > Use prefix increment instead, like > this: > > a = ++a; You might think so, but you would be horribly wrong. This line has completely undefinied behavior. > Of course, it's advisable you take into account all other advises > about prototype of main() and enting output with \n. ![]() Of course, it's advisable for you to learn about sequence points before posting "advice". |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
NicoleaSW@gmail.com wrote:
> On Dec 25, 12:46 pm, Port Pirie <no...@nospam.invalid> wrote: >> Hi, >> >> I ran the program below. It should print out 2 but actually it prints >> out 1. What's going on? Should I report a bug against the compiler? >> >> Thanks. >> >> void main() >> { >> int a=1; >> a=a++; >> printf("%d", a); >> >> } > > The key point to your answer is the line: > a=a++; > > it evaluates a to 1 in right side, assigns 1 to a in left side, then > increments a used in right side. Wherever you learned that from, reconsider its educational value; it's wrong. It's a /permitted/ implementation, but only because the expression `a = a++` has /no/ defined behaviour -- anything and everything is permitted. There are specific words in the Standard that, amongst other things, make undefined the effects of writing to the same location multiple times without an intervening "sequence point". Don't Do That. -- Oh Noes! I Has Meltdownz! Hedgehog "Life is full of mysteries. Consider this one of them." Sinclair, /Babylon 5/ |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
santosh wrote:
> Port Pirie wrote: > >> Hi, >> >> I ran the program below. It should print out 2 but actually it prints >> out 1. What's going on? Should I report a bug against the compiler? >> >> Thanks. >> >> >> void main() >> { >> int a=1; >> a=a++; >> printf("%d", a); >> } > > You have invoked undefined behaviour thrice. Firstly void main is not > the proper prototype. Proper forms are int main(void) or int main(int, > char**). Secondly you access an object to modify it's value twice > within a sequence point. Thirdly you are calling a variadic function > with no prototype in scope. > > Please read the FAQ at the following link: > > <http://www.c-faq.com/> > <http://www.clc-wiki.net/> > Why don't you answer his question? If his complier isn't issuing warnings about these things he may indeed need to report a bug, just not the one he thinks. |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
"Golden California Girls" <GldnCAGrls@aol.com.mil> wrote in message news:XK6dnXfJt8bB0OzanZ2dnUVZ_o2vnZ2d@championbroa dband.com... > santosh wrote: >> Port Pirie wrote: >> >>> Hi, >>> >>> I ran the program below. It should print out 2 but actually it prints >>> out 1. What's going on? Should I report a bug against the compiler? >>> >>> Thanks. >>> >>> >>> void main() >>> { >>> int a=1; >>> a=a++; >>> printf("%d", a); >>> } >> >> You have invoked undefined behaviour thrice. Firstly void main is not >> the proper prototype. Proper forms are int main(void) or int main(int, >> char**). Secondly you access an object to modify it's value twice >> within a sequence point. Thirdly you are calling a variadic function >> with no prototype in scope. >> >> Please read the FAQ at the following link: >> >> <http://www.c-faq.com/> >> <http://www.clc-wiki.net/> >> > > Why don't you answer his question? The first question ("What's going on?") was answered: The behavior is undefined, thus *anything* is possible, including the reported result. > If his complier isn't issuing warnings about > these things he may indeed need to report a bug, just not the one he > thinks. And above the second question ("Should I report a bug against the compiler?") was also answered. AFAIK, there's nothing in his code for which the standard requires a diagnostic. Warnings might be nice, but that's simply a quality-of-implementation issue, not a 'bug'. -Mike |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Mike Wahler wrote:
> "Golden California Girls" <GldnCAGrls@aol.com.mil> wrote in message > news:XK6dnXfJt8bB0OzanZ2dnUVZ_o2vnZ2d@championbroa dband.com... >> Why don't you answer his question? > > The first question ("What's going on?") was answered: The > behavior is undefined, thus *anything* is possible, including the > reported result. > >> If his complier isn't issuing warnings about >> these things he may indeed need to report a bug, just not the one he >> thinks. > > And above the second question ("Should I report a bug against the > compiler?") > was also answered. > > AFAIK, there's nothing in his code for which the > standard requires a diagnostic. Warnings might > be nice, but that's simply a quality-of-implementation > issue, not a 'bug'. > So the standard doesn't require some message or action when you depart from it. Interesting. I'd say not a good standard, in fact not a standard at all. Why even have it? |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
Golden California Girls wrote:
> Mike Wahler wrote: >> "Golden California Girls" <GldnCAGrls@aol.com.mil> wrote in message >> news:XK6dnXfJt8bB0OzanZ2dnUVZ_o2vnZ2d@championbroa dband.com... >>> Why don't you answer his question? >> >> The first question ("What's going on?") was answered: The >> behavior is undefined, thus *anything* is possible, including the >> reported result. >> >>> If his complier isn't issuing warnings about >>> these things he may indeed need to report a bug, just not the one he >>> thinks. >> >> And above the second question ("Should I report a bug against the >> compiler?") >> was also answered. >> >> AFAIK, there's nothing in his code for which the >> standard requires a diagnostic. Warnings might >> be nice, but that's simply a quality-of-implementation >> issue, not a 'bug'. >> > > So the standard doesn't require some message or action when you depart > from it. Interesting. I'd say not a good standard, in fact not a > standard at all. Why even have it? Syntax errors and constraint violations must produce a diagnostic but other issues can be left undiagnosed by an implementation. It must also document it's behaviour for all issues the Standard tags as "implementation defined". It need not document undefined behaviour. |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
On Tue, 25 Dec 2007 16:05:56 -0800, Golden California Girls wrote:
> So the standard doesn't require some message or action when you depart > from it. > Interesting. I'd say not a good standard, in fact not a standard at > all. Why > even have it? The standard requires messages for the types of departures that can be realistically diagnosed in the general case at compile time. If it mandated anything beyond that, I doubt the standard would be more useful than now; we would merely have more implementations that don't conform to it. |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
santosh wrote:
> Golden California Girls wrote: > >> Mike Wahler wrote: >>> "Golden California Girls" <GldnCAGrls@aol.com.mil> wrote in message >>> news:XK6dnXfJt8bB0OzanZ2dnUVZ_o2vnZ2d@championbroa dband.com... >>>> Why don't you answer his question? >>> The first question ("What's going on?") was answered: The >>> behavior is undefined, thus *anything* is possible, including the >>> reported result. >>> >>>> If his complier isn't issuing warnings about >>>> these things he may indeed need to report a bug, just not the one he >>>> thinks. >>> And above the second question ("Should I report a bug against the >>> compiler?") >>> was also answered. >>> >>> AFAIK, there's nothing in his code for which the >>> standard requires a diagnostic. Warnings might >>> be nice, but that's simply a quality-of-implementation >>> issue, not a 'bug'. >>> >> So the standard doesn't require some message or action when you depart >> from it. Interesting. I'd say not a good standard, in fact not a >> standard at all. Why even have it? > > Syntax errors and constraint violations must produce a diagnostic but > other issues can be left undiagnosed by an implementation. It must also > document it's behaviour for all issues the Standard tags > as "implementation defined". It need not document undefined behaviour. > I'm assuming the "It" you mention in your second sentence should read "The implementation". Your third sentence the "It" could stand for either "The standard" or "The implementation". In any case I'm not talking about some hypothetical implementation, I'm talking about the standard itself. My point is that the standard should not allow undefined behavior. It should either tag it implementation defined so it gets documented or tag it as a syntax or constraint violation. Leaving things undefined is like how houses used to be wired in the USA. There was a plug and you knew there was a neutral pin and a hot pin but had no clue which pin had which, because the standard left it undefinable. People died because of that. [1] Perhaps the standard had better start with big bold face caps "This standard leaves things undefined and therefore must not be used in any case where harm (economic or physical) might come to anyone such as any real world application." [1] It is Christmas time so a perfect example. Strings of lights used to have fuses on each lead. Why? Because the person making the string of lights didn't know which lead was hot. He had to hope the short tripped both fuses so the string went cold. Fuses however don't all open at the same point. Sometimes the one in the line that was cold opened first and the string was left hot. Now there is a big safety issue on a fake metal Christmas tree or a real one that tipped over and spilled water all over the floor. Today however because the designer knows which lead is hot there is only one fuse and it is in the hot lead. It opens and the string is safe. Standards should not leave things undefined! |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
In article <qdCdncOZDrazT-zanZ2dnUVZ_rmjnZ2d@championbroadband.com>,
Golden California Girls <GldnCAGrls@aol.com.mil> wrote: >My point is that the standard should not allow undefined behavior. ... In general, the more you pin things down, the slower they will have to go. As we see over and over again in computing, it is more important to get the wrong answer as fast as possible. :-) Seriously, there *are* languages that have no undefined behavior, and languages that are much better specified than C (Ada, for instance, falls into the latter category). If that is what you want, you should consider these languages. There is a price to pay for this, though. As for defining all behavior precisely, consider the following function: void f(int *p, int *q) { *p = (*q)++; } The semantics of this function, as defined by the C standard, say that *p will be set to whatever *q used to have, and *q will be incremented, so that: int a, b = 42; ... f(&a, &b); leaves a set to 42, and b set to 43. But what happens if we do: f(&b, &b); ? The "C answer" is: "the effect is undefined". This makes it easy for a compiler to generate code for f() that runs as fast as possible, even if that means that this has some strange effect on b() in a call like the last one. Now, you might argue that the compiler should be able to detect that p and q both point to b, so that the call to f() should draw a diagnostic. In some languages, it is possible to specify this -- but C is not one of those languages. In C, f() can be compiled separately from the call to f(), and by the time you go to join the two together (the "link phase"), the information needed is allowed to have been, and usually has been, discarded. Alternatively, you might argue that the compiler should be required to generate code for f() that does something "well defined" even if p and q both point to b. Some languages take such an approach -- but C is not one of those languages either; C allows compilers to generate the fastest possible code, as long as it gets the right answer whenever p and q point to different variables. The original C standardization effort, which by most accounts was wildly successful, attempted -- for the most part at least -- to standardize existing practice, without inventing new features like detecting invalid calls to f(). The C89 standard was rapidly adopted quite widely. The later standardization effort, resulting in C99, was clearly less successful: and it took the approach of improving the language in various ways, inventing new features to make programming easier and/or safer, instead of sticking with existing practice. I leave it to the reader to draw conclusions. (Well, one of mine -- not 100% serious, admittedly -- is at the top of this article. :-) ) -- 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. |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
On Tue, 25 Dec 2007 16:05:56 -0800, Golden California Girls wrote:
> So the standard doesn't require some message or action when you depart > from it. Not correct. Many classes of error e.g. syntax errors and constraint violations, require a diagnostic. Others are left to the implementation to decide how to handle because the result is implementation dependent. For example some implementations support a startup function signature void main(), so forcing an implementation to error this would be wrong. |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
Mark McIntyre said:
> On Tue, 25 Dec 2007 16:05:56 -0800, Golden California Girls wrote: > >> So the standard doesn't require some message or action when you depart >> from it. > > Not correct. > Many classes of error e.g. syntax errors and constraint violations, > require a diagnostic. In fact, those are two of only three classes of error for which the Standard requires a diagnostic message during translation. The third is deliberately programmer-induced: #error. -- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ Google users: <http://www.cpax.org.uk/prg/writings/googly.php> "Usenet is a strange place" - dmr 29 July 1999 |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
On Tue, 25 Dec 2007 20:01:42 -0800, Golden California Girls wrote:
> > My point is that the standard should not allow undefined behavior. That's a foolish point. If it did not allow some behaviour to be undefined, then it would have to document all behaviour on all platforms now and as-yet uninvented. Thats obviously impossible. Furthermore it would proscribe implementations from providing extensions since if everything is defined, nothing can be added. > Perhaps the standard had better start with big bold face caps "This > standard leaves things undefined and therefore must not be used in any > case where harm (economic or physical) might come to anyone such as any > real world application." Perhaps it could start with "this standard expects its readers to have common sense, if you're too stoopid to wire up a 3-pin plug, then stop now". > [1] It is Christmas time so a perfect example. Strings of lights used > to have fuses on each lead. Why? Because if the cable broke half way along, both halves would be carrying current and you could get fried off each half. >Because the person making the string > of lights didn't know which lead was hot. Euh? Do you guys use DC in the states? If not, it doesn't matter which is live, they're both carrying 240/110 V. Follow 'em back to the pole where the phases split out.... |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
On Wed, 26 Dec 2007 04:37:07 +0000, Chris Torek wrote:
> Now, you might argue that the compiler should be able to detect that p > and q both point to b, so that the call to f() should draw a diagnostic. Though that's tricky if, as Chris notes, the function f() is in a library that was compiled long long ago on a computer far far away -or worse yet, is still being written by a co-worker 14,000 miles away in a different timezone. I'm not aware of any compilers that can diagnose either the past or the future! > In C, f() can be compiled > separately from the call to f(), and by the time you go to join > the two together (the "link phase"), the information needed is > allowed to have been, and usually has been, discarded. .... and even if it hasn't, the runtime environment might be presented with duff user input, eg the user was told to pick two _different_ objects but chose the same one twice. A lot of gets() type bugs come lack of /programmer/ effort to assist users who enter "ten" instead of "10"... Remember - if you design an idiot-proof system, the universe will design a better class of idiot. |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
On Wed, 26 Dec 2007 11:46:27 +0000, Mark McIntyre wrote:
> On Tue, 25 Dec 2007 20:01:42 -0800, Golden California Girls wrote: >> My point is that the standard should not allow undefined behavior. > > That's a foolish point. If it did not allow some behaviour to be > undefined, then it would have to document all behaviour on all platforms > now and as-yet uninvented. As the most simplistic example, it could say that everything not explicitly defined is implementation-defined. Alternatively, it could provide a reference implementation and require other implementations to behave the same way, except where the behaviour is explicitly unspecified. There are probably other possibilities I haven't thought of. None probably would have worked well for C, but it's not nearly as absurd as you suggest it is. |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
On Wed, 26 Dec 2007 14:00:16 +0100, Harald van Dijk wrote:
>> As the most simplistic example, it could say that everything not > explicitly defined is implementation-defined. I think's playing with words. The difference between IB and UB is an artefact of the standard. Also practically speaking, no document can define all behaviours - it'd take an infinite amount of paper. Even the Ada standard doesn't define what happens if I compile the code on Boxing Day while naked and playing pinochle. > Alternatively, it could > provide a reference implementation and require other implementations to > behave the same way, except where the behaviour is explicitly > unspecified. Yes, this approach is often used. The difficulty is that while it works fine for stuff thats highly prescribed in the first place (say the definition of a kilogram), it doesn't work well for general-purpose stuff. In the case of programming languages, it would force implementations to support non-native features, which can be exceptionally costly in terms of both dev effort and runtime. > it's not nearly as absurd as you suggest it is. Consider which languages are popular, widely ported and widely used. Are they the ones with fully prescriptive standards? Or are they the ones that leave the implementor plenty of scope to handle some behaviours as best suits their environment? |
|
|
|
#24 |
|
Messages: n/a
Hébergeur: |
Mark McIntyre wrote, On 26/12/07 11:46:
> On Tue, 25 Dec 2007 20:01:42 -0800, Golden California Girls wrote: <snip> >> Because the person making the string >> of lights didn't know which lead was hot. > > Euh? Do you guys use DC in the states? If not, it doesn't matter which is > live, they're both carrying 240/110 V. Follow 'em back to the pole where > the phases split out.... Actually that is wrong in the UK. The neutral is bonded to earth at the sub-station, although at your house it will be a bit away from the ground voltage. See, for example, page 19 and on of this document http://www2.theiet.org/Publish/WireR...no_adverts.pdf It is the live that varies with respect to ground at the sub-station, and this is why it is important that the live and neutral are not swapped in your house. This is all OT here so if you want to continue the discussion one sensible place would be the IET forums which will be somewhere on http://www.theiet.org/ -- Flash Gordon |
|
|
|
#25 |
|
Messages: n/a
Hébergeur: |
Mark McIntyre <markmcintyre@spamcop.net> writes:
> On Tue, 25 Dec 2007 20:01:42 -0800, Golden California Girls wrote: >> My point is that the standard should not allow undefined behavior. > > That's a foolish point. If it did not allow some behaviour to be > undefined, then it would have to document all behaviour on all platforms > now and as-yet uninvented. Thats obviously impossible. Furthermore it > would proscribe implementations from providing extensions since if > everything is defined, nothing can be added. No, it's not obviously impossible. A language standard could rigorously define the behavior of an abstract machine, and require all implementations to implement that abstract machine exactly. But such a language wouldn't really be C, even if it superficially looked like it. In particular, implementations for real systems that differ from the abstract machine couldn't easily take advantage of those systems' features. >> Perhaps the standard had better start with big bold face caps "This >> standard leaves things undefined and therefore must not be used in any >> case where harm (economic or physical) might come to anyone such as any >> real world application." > > Perhaps it could start with "this standard expects its readers to have > common sense, if you're too stoopid to wire up a 3-pin plug, then stop > now". Perhaps that's not the best example. I don't know how to wire up a 3-pin plug -- not because I'm stoopid, just because I've never had a need to do it. [...] -- Keith Thompson (The_Other_Keith) <kst-u@mib.org> [...] "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
![]() |
| Outils de la discussion | |
|