3

I am reading a post, in one of the answers there is the following code

#define goto { int x = *(int *)0; } goto

There the author states that every time a person tries to use a goto statement, his program will crash, my question is why? According to my understanding, int x = *(int *)0; assigns the whatever content in the first 4 bytes of the memory address to x, but why this will for sure crash the program?

Community
  • 1
  • 1
Allanqunzi
  • 3,230
  • 1
  • 26
  • 58
  • 4
    This author should not be writing programs, removing an essential part of c programming like the very useful `goto` just because they don't know how to use it. ... ? And also, saying it will crash the program is wrong, it will invoke undefined behavior, and hence the behavior of the program is unpredictable. Which means that this prevents nothing while it causes unknown problems. So, if I were you, I would look for a different book. – Iharob Al Asimi Apr 18 '15 at 20:39
  • 1
    @iharob: It is not some book OP is referring to but to an upvoted SO answer. Sometime I feel so depressed on seeing meaningless answers upvoted by community – Abhijit Apr 18 '15 at 20:45
  • 1
    @downvoters: Please do not downvote this question but rather the upvoted SO answer linked to this question that are misleading posters like OP. – Abhijit Apr 18 '15 at 20:47
  • 1
    If you feel you must punish the use of `goto`, an unreliable runtime error is a silly way to do it. Better: `#define goto @` will force a syntax error for any use of `goto`. Better yet, you can ban `goto`s in your coding standard; if you can't trust your programmers to follow the coding standard you've got bigger problems. – Keith Thompson Apr 18 '15 at 21:20

3 Answers3

7

Simply because you are dereferencing a NULL pointer. But then that the program will crash is not defined. It may crash, may not crash or do something weird. It is just an undefined behaviour and is best to avoid.

It is worth noting that goto is not that useless. Every keyword has its own place and the language authors and members of standard committee have reasons to still maintain it (considering languages are going some dramatic changes). If use judiciously, goto has a deserving place in C and C++.

Just to give an idea how this is an UB, using VC11, I compiled the above snippet in debug and release mode. In debug mode it crashed but in release mode, compiler simply optimized out the statement and there was no crash.

Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • change the code to `#define goto { int x = *(int volatile*)0; } goto` to get more consistent crashes. – chqrlie Apr 18 '15 at 22:51
0

In C or C++, the memory address 0 represents a NULL pointer. Dereferencing such a pointer is always undefined behavior and on most implementation it provokes a segmentation faults, effectively "crashing" the program.

rems4e
  • 3,112
  • 1
  • 17
  • 24
  • 1
    The conversion to a pointer type of `0` is a null pointer. It doesn't have to be the memory address 0. Dereferencing a null pointer is undefined behavior and the compiler can generate code with arbitrary behavior along executions that do so. – Pascal Cuoq Apr 18 '15 at 20:43
  • From the point of view of the C++ runtime, a pointer containing the value 0 does point to the address 0 doesn't it? I'm not talking of the virtual address, maybe it was so clear. – rems4e Apr 18 '15 at 20:47
  • No, the conversion to pointer of the value 0 does not have to be the address 0. In C, this is covered in section 5 of the C FAQ: http://c-faq.com/null/index.html (see in particular 5.3 and 5.5). C++ does not have any additional rules in this respect that would force the bit pattern of a null pointer to represent 0. – Pascal Cuoq Apr 18 '15 at 20:54
  • Again, when I say a pointer with value 0, I mean a pointer which was affected the 0 integer literal in the language. From the point of view of the language, the value will always be 0, as you can latter check the equality against 0. I never talked about the bit pattern, I only talked about an address 0, agnostic from any underlying architecture. Taking the address of an object located at address X yields a pointer with value X, hence my parallel between address and pointer value. – rems4e Apr 18 '15 at 21:13
  • @rems4e: It seems you are confusing real address with virtual address – Abhijit Apr 18 '15 at 21:16
  • @Abhijit What makes you think so? I took care to not mention real addresses in my discussion, as they are completely unrelated to the Q/A and comments anyway. – rems4e Apr 18 '15 at 21:31
  • You didn't say “a pointer with value 0”. You said “the memory address 0”, something that doesn't make any sense in the C or C++ standards (objects and functions have addresses. Addresses are not integers. There is no “address 0” and no “address 17” in the standards). On the other hand, at a lower level, “address” is the name of the keys of the map from integers to values called “memory”. A null pointer doesn't have to be the key 0 of this map. – Pascal Cuoq Apr 18 '15 at 22:02
  • In other words: `{ void *p, *q; p = 0; memset(&q, 0, sizeof q); return memcmp(&p, &q, sizeof q); }` does not necessarily return `0`. I don't actually know any physical computer where it wouldn't, but so says the C standard. – chqrlie Apr 18 '15 at 22:58
0

The code gives undefined behaviour on two counts.

Firstly, redefining a language keyword in itself yields undefined behaviour.

Second, as others have said, a pointer with value `0' is the NULL pointer, and dereferencing it gives undefined behaviour.

The actual result of the construct is therefore undefined behaviour. A common symptom of undefined behaviour is a program crash. However, a crash is not actually guaranteed. It is not even required.

As the the "why?" of writing the macro, the author of that code is obviously a subscriber to the "goto is evil" camp, and sees fit to arbitrarily inflict his/her uninformed prejudices on others. In reality, goto has its uses even if alternatives are often preferable. Even Dijkstra (the author of the original paper that people often cite to justify not using goto) only described problems of unbridled use, and did not claim it should be simply avoided. Donald Knuth later wrote a paper on the topic in the mid 70s, including examples where use of goto is beneficial.

Peter
  • 35,646
  • 4
  • 32
  • 74