different result for allocated uninitialized int*

The following 2 different codes are giving different results even though the result has nothing to do with the deleted code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <array>
#include <vector>
using namespace std;
int main()
{
    std::vector<int> value_initialized ;
    std::cout << "value_initialized: " ;
    for( int i : value_initialized ) std::cout << i << ' ' ; 
    std::cout << '\n' ;

    std::vector<int> default_initialized ;
  
    
    double* x1 = new double;
    double* x2 = new double();
    double* x3 = new double{};
    double* x4 = new double[5];
    cout<<endl<<*x1<<endl<<*x2<<*x3<<*x4;
     

}



http://coliru.stacked-crooked.com/a/e86fced544a4508a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#include <iostream>
#include <array>
#include <vector>
using namespace std;
int main()
{
    std::vector<int> value_initialized ;
    
    std::vector<int> default_initialized ;
  
    
    double* x1 = new double;
    double* x2 = new double();
    double* x3 = new double{};
    double* x4 = new double[5];
    cout<<endl<<*x1<<endl<<*x2<<*x3<<*x4;
     

}



http://coliru.stacked-crooked.com/a/97df60e379268254


gcc is giving the same result for *x1 but clang is not..

q1)Why is this happening as there is no link of *x1 with anything?

q2)is it that one of the compilers are wrong or the site is not constructed well?


More confusion: Extra info : *x1 is giving a large value 6.95327e-310 on Xcode running on llvm clang 5.1
under all conditions
Last edited on
1
2
double* x1 = new double; // uninitialised double
std::cout << *x1 ; // use value of uninitialised and unassigned scalar 

engenders undefined behaviour.

This is fine:
1
2
3
double* x1 = new double; // uninitialised double
*x1 = 45.678 ; // assign value to the uninitialised double
std::cout << *x1 ; // and use its value 

Last edited on
are the values of *x2 AND *x3 also UB
x2 and x3 are initialized to 0.0.

Your value_initialized and default_initialized arrays have zero size.

Finally, it isn't that the behavior of the std::cout << *x1 is undefined, but that the value of *x1 is undefined. This behavior is well defined: it will print the value of x1, but that value might be anything.

"Undefined value" means that the compiler and operating system can put whatever they want there. Different compilers can put different things there. Adding or changing other code can cause the value to change. Basically it means "don't complain about what's there. Ever."
> it isn't that the behavior of the std::cout << *x1 is undefined,

It is undefined behaviour.
Not even undefined behaviour by omission - "Undefined behavior may be expected when this International Standard omits any explicit definition of behavior".
This is explicitly specified undefined behaviour.

Lvalue-to-rvalue conversion
A glvalue of a non-function, non-array type T can be converted to a prvalue. ...
If the object ..., or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.
Footnote: For historical reasons, this conversion is called the “lvalue-to-rvalue” conversion, even though ... - IS



> are the values of *x2 AND *x3 also UB

If a program engenders undefined behaviour, then the entire program has undefined behaviour (the IS "places no requirement on the implementation executing that program").

However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).
are the following comments describe the initialisation in the right way :

1
2
3
4
5
6
7
8
  vector<int> v1; // empty vector
    vector<int> v2(); // empty vector
    vector<int> v3{}; // empty vector
    vector<int> v4{1}; // v4 contains 1 element whose value is 1
    vector<int> v5{1,2,3,4,5}; // vector v4 contains 5 elements whose value is 1,2,3,4,5
    vector<int> v6(32,9); // v6 contains 36 elements with each having a value of 9
    vector<int> v7 = {1,2,3,4,5}; //same as v5
    vector<int> v8(32,9); // 32 elements initialized to 9 
Yes, except for:
std::vector<int> v2(); // empty vector declares function v2

This may be of interest:
1
2
3
4
5
std::vector<int> v4{1}; // v4 contains 1 element whose value is 1
std::vector<int> v41(1); // v41 contains 1 element whose value is zero

std::vector<int> v8(32,9); // 32 elements initialized to 9 
std::vector<int> v81{32,9}; // size is 2,  elements are 32, 9  
Topic archived. No new replies allowed.