0

Is there UB in the following code?

#include <stdio.h>

int main(void)
{
    int x;
    printf("%d", 0*x);
    return 0;
}

Here, the variable x was not initialized, but was multiplied by 0 and the result was passed to printf. Mathematically, the result passed to printf should be 0, but I guess that in c language this invokes UB. If the variable was not multiplied by 0 it is clearly UB but I am not sure is it UB in this particular case.

Ideone link

ks1322
  • 33,961
  • 14
  • 109
  • 164
  • UB is not "something bad happens". UB is "compiler is allowed to do anything it wants". Using uninitialized value is a permission to compiler to do anything - including returning 0. – aragaer May 10 '17 at 12:35
  • 1
    You'll probably hit UB _before_ multiplication. – Sourav Ghosh May 10 '17 at 12:37
  • 1
    @SouravGhosh this should be a better duplicate [Is a^a or a-a undefined behaviour if a is not initialized?](http://stackoverflow.com/q/25074180/995714) – phuclv May 10 '17 at 12:37
  • @LưuVĩnhPhúc Sure, just added that. :) – Sourav Ghosh May 10 '17 at 12:38
  • ...and someone would do this because......? – ThingyWotsit May 10 '17 at 12:38
  • 1
    Better duplicate still: [(Why) is using an uninitialized variable undefined behavior in C?](http://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior-in-c). – Lundin May 10 '17 at 14:15

2 Answers2

3

Yes, it's UB.

A conforming compiler may not do any optimization and run into a trap representation in x.
Some implementations may reserve some bits for special values, including trap representations.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • I do not think that it is UB. - simply `x` can be given any junk value and `0*x` will be 0. – Ed Heal May 10 '17 at 12:32
  • Why downvotes for this answer ? – Destructor May 10 '17 at 12:32
  • @EdHeal: some implementations may reserve some bits of `int` for trap values. – pmg May 10 '17 at 12:34
  • @EdHeal, not just trap representations, some compilers might also run into bad optimizations because of the UB. – Ajay Brahmakshatriya May 10 '17 at 12:40
  • What are the trap representations for an `int`? – Ed Heal May 10 '17 at 12:43
  • Usual hardware (Intel, AMD, ...) does not have the concept of trap representation. But imagine a 9-bit computer where it finds a value with all 9 bits set to 1 causes it to reboot. – pmg May 10 '17 at 12:56
  • ...although traps representations for integer values are highly unlikely today. – Jabberwocky May 10 '17 at 12:57
  • If `int` does not have a trap value, will the behaviour be undefined? – Ed Heal May 10 '17 at 14:09
  • 1
    It is not UB because of trap representations, but because the variable has automatic storage and never has its address taken. [See this](http://stackoverflow.com/a/40674888/584518). Trap representations are mostly irrelevant in real-world computers. If this variable had its address taken and the system did not support trap represenation, it would have been merely unspecified behavior. – Lundin May 10 '17 at 14:18
  • Would it be unspecified behavour in the latter case? – Ed Heal May 10 '17 at 14:51
  • @Lundin: On gcc 5.4.1 for the ARM, using `memcpy` to copy a partially-written struct containing two `uint16_t` values may yield a copy with a field containing a value outside the range 0-65535. Using `memcpy` on a partially-written structure should be defined behavior, but gcc sometimes optimizes away the `memcpy`, even though it would render otherwise-undefined behavior, defined. – supercat May 10 '17 at 22:37
  • @supercat What does that have to do with trap representations? The ARM ABI does not have trap representations. It rather sounds like something related to pointer aliasing, which has nothing to do with this topic. – Lundin May 11 '17 at 06:58
  • @Lundin: You say that a defining factor is that an object's address is not taken. Applying `memcpy` to an object implies taking its address, thus forbidding a compiler from regarding it as an "object of automatic duration whose address has not been taken". The only other way that reading object of an unsigned integer type could behave as though it yielded an object outside its range would be if it could hold a trap representation. – supercat May 11 '17 at 12:54
  • @supercat memcpy does indeed mean that the address is taken. The UB related to automatic storage duration variables means that they might be allocated in CPU registers unless you take their address. If the address is taken, then that part isn't relevant and you end up with an indeterminate value, which could either be an unspecified value (in 99.99% of all real-world computers) or a trap representation (in wildly exotic, barely existing computers). Again, the issue you describe seems related to pointer aliasing and not to indeterminate values. – Lundin May 11 '17 at 13:07
  • @Lundin: My point is that some optimizers will replace code that takes an object's address with code that doesn't, and then treat the object as though the address isn't taken. – supercat May 11 '17 at 16:13
  • Am I right that UB is invoked exactly in this piece of code: `0*x` ? And not somewhere inside `printf` when the value is about to be printed ? – ks1322 May 11 '17 at 16:42
  • @supercat The standard is clear, so if a compiler does something else, then it is not conforming. – Lundin May 12 '17 at 06:34
  • @ks1322 Yes you invoke UB as soon as `x` is accessed. It is a local variable and its address had not been taken, so it is UB as per 6.3.2.1. – Lundin May 12 '17 at 06:35
1

This is undefined behavior, as this may cause a trap representation.

From the C standard:

Uniitialized variables, section 6.7.9:

10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

The definition of indeterminate, Section 3.19.2:

indeterminate value

either an unspecified value or a trap representation

The definition of trap representation, Section 3.19.4:

trap representation

an object representation that need not represent a value of the object type

dbush
  • 205,898
  • 23
  • 218
  • 273
  • What are the trap representations for an int? – Ed Heal May 10 '17 at 12:44
  • No this is not (necessarily) why this is UB. [See this](http://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior-in-c/40674888#40674888). In real-world computers there exist no trap representations so any discussion about them is irrelevant to the real world. – Lundin May 10 '17 at 14:20