0

In C++, having primitive type (int, double, char, ...) not-defined so undefined behaviour. There is no default value for primitive types, because they have no constructor. But the compiler is consistent giving default value (0), when there is no context:

int main(){
 int x;
 std::cout << x << std::endl;
}

will always give 0 (compiled cc -lstdc++).

However, having some context (i.e. not just printing it), the value is random:

#include <algorithm>
#include "student.hpp"

using std::max;

int main(){
    int x;
    Student_struck s = {.name = "john"};
    std::cout << max(s.name.size(), (std::size_t)x) << std::endl;
}

here, the same compilation, but every time different result:

21898, 22075, 22020, 21906, ...

What is gcc implementation for primitive not-defined variables?

It is even more strange, that in comparison with C, I can have

#include <stdio.h>

int main(){
    int i;
    printf("%i\n",i);
}

And the compiler is always consistent, with giving 0 as default value. So the same compiler, but different language for the same primitive types give different results. I would really like to know what is the implementation for C++ library to handle non-defined primitive variables.

What is difference between primitive types in C vs in C++. I am not asking about the UB, but only how are those types defined in both language and difference between them

Acorn
  • 24,970
  • 5
  • 40
  • 69
milanHrabos
  • 2,010
  • 3
  • 11
  • 45
  • 6
    No, the only thing that the compiler is being consistent about is [making demons fly out of your nose](https://en.wiktionary.org/wiki/nasal_demon). This is undefined behavior. Today you might get 0. Tomorrow, you might get 42. And the next day your computer can catch on fire. This is what undefined behavior means. – Sam Varshavchik Jul 07 '20 at 11:03
  • Is your question about C++ rules or why GCC in particular has this behavior? – Aykhan Hagverdili Jul 07 '20 at 11:03
  • Most likely it has something to do with memory underneath. It may just happen that creating another variable pushes `int x` to a different memory location, where there are some leftovers (perhaps leftover stack after calling constructor). But, as with all Undefined Behaviour, it may be whatever it wants. – Yksisarvinen Jul 07 '20 at 11:04
  • @_Static_assert asking about compiler-implementation or rules for non-defined, primitive (that have no constructor) vars. Sam Varshavchik - no, in `c` language the compiler will *always* give `0` despite `c++`. Compiler will give a warning in `c`. but never gives something other then `0`. Tried multiple times – milanHrabos Jul 07 '20 at 11:06
  • @_Static_assert moreover, compiler *could* have *default* value for those primitive types. Why did compiler devs made it UB, when could be default for primitive types? – milanHrabos Jul 07 '20 at 11:08
  • @mil your question is really based on some wrong assumptions you have. Please read into how built-in types are initialized and delete this question. – Aykhan Hagverdili Jul 07 '20 at 11:08
  • 2
    "_There is no default value for primitive types, because they have no constructor._" - An object with static or thread-local storage duration gets [zero-initialized](https://en.cppreference.com/w/cpp/language/zero_initialization), so by just making it `static int x;` you would have a zero-initialized `x`. – Ted Lyngmo Jul 07 '20 at 11:16
  • Please use C and C++ for the name of the language (uppercase, no code tag). – Acorn Jul 07 '20 at 11:22
  • 1
    Many compilers will 0 initialize values in *debug* builds, but don't do so in optimized builds. Try turning on optimizations and things will likely change. – Jesper Juhl Jul 07 '20 at 11:55

2 Answers2

2

In C++, having primitive type (int, double, char, ...) not-defined so undefined behaviour.

I think you mean uninitialized - and just having them uninitialized is not undefined behavior. It's in fact common when you know that you'll assign a value to them before you later read them.

There is no default value for primitive types, because they have no constructor.

An object with static or thread-local storage duration gets zero-initialized.

in comparison with C, I can have...

You have observed one particular behavior of the many allowed behaviors your program can have. The C standard says:

[6.7.9]/10 Initialization in C (emphasis mine):

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

  • If an object that has static or thread storage duration is not initialized explicitly, then:

    — if it has pointer type, it is initialized to a null pointer;

    — if it has arithmetic type, it is initialized to (positive or unsigned) zero;

    — if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

    — if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

So it seems your assumption is wrong. The compiler is not required to be consistent. It may do it differently in different parts of your program, depending on optimization flags and what day of the week it is etc.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • 1
    And still, technically, the C code presented is undefined behavior, but [not from the reasons one expects](https://stackoverflow.com/questions/11962457/why-is-using-an-uninitialized-variable-undefined-behavior). – KamilCuk Jul 07 '20 at 12:41
  • @KamilCuk The C++ code? Sure, I had no doubt. In C, I don't know. There's no risk of a trap representation. Do you mean that it could be in a register (even though `register` wasn't used) since its address has not been taken and that reading it therefore has UB? I can buy that if that's the case. – Ted Lyngmo Jul 07 '20 at 12:53
  • 1
    `Do you mean...?` Yes. – KamilCuk Jul 07 '20 at 13:00
0

the compiler is consistent giving default value (0)

Perhaps, but that is something you cannot rely on.

What is gcc implementation for primitive not-defined variables?

Very hard to say without looking into the source code and tracking the execution to see what would happen in your particular case (optimization flags, compiler version, input code...).

And the compiler is always consistent, with giving 0 as default value.

Try adding code around and you will likely be able to see "random" values with C too.

So the same compiler, but different language for the same primitive types give different results.

The fact that you are using the same compiler is not a guarantee that behavior will always hold. Even if you were to always use the exact same compiler version and same build flags, the behavior could change for different input code.

Acorn
  • 24,970
  • 5
  • 40
  • 69
  • I think that this question has been asked and answered over and over on the site before. See [this](https://stackoverflow.com/q/30172416) for instance. I don't think we need to answer it again. – Aykhan Hagverdili Jul 07 '20 at 11:11
  • @_Static_assert are you getting a little bit nervous? This is not that hard question, is it? – milanHrabos Jul 07 '20 at 11:12
  • @mil your question shows no sign of research. Such questions are unwelcome on Stack Overflow. – Aykhan Hagverdili Jul 07 '20 at 11:14
  • 1
    @milanHrabos Answering questions multiple times makes it more difficult for others to find them and keep the answers relevant. Imagine that for example C++23 standard would decide that all variables should be initialized, now we need to find every single duplicate question and update answers there to reflect the current state of the art. – Yksisarvinen Jul 07 '20 at 11:15
  • @_Static_assert I have eddited the question. You suggestion on different question are for the plain `c++`. My question is rather comparison between two languages, `c` and `c++`. That is not the same – milanHrabos Jul 07 '20 at 11:16
  • @_Static_assert Sure, but answering particular instances of a question still helps new people to a language. The question can still be marked as duplicate, that is fine. – Acorn Jul 07 '20 at 11:18
  • @mil [C duplicate](https://stackoverflow.com/q/11233602/10147399) – Aykhan Hagverdili Jul 07 '20 at 11:18
  • @Yksisarvinen Each revision of the C++ standard is a different language, so that is not a problem. Given answers are timestamped, it is easy to tell if something is out of date. – Acorn Jul 07 '20 at 11:19
  • @Acorn this question is tagged with [C++], not a specific revision like [C++20]. It seems to be about C++ in general and not a particular revision. My [comment](https://stackoverflow.com/questions/62773759/primitive-types-in-c-vs-in-c#comment111008621_62773907) was a mere suggestion in any case. – Aykhan Hagverdili Jul 07 '20 at 11:27
  • @_Static_assert Yeah, but that has always been a problem with the generic tag. There is no way one can know what the future standards will say, so... – Acorn Jul 07 '20 at 11:31