Usage of reference that has not yet been initialized - c++

Having the following small example, which is obvious not working, because the used reference has not yet been initialized when used.
#include <iostream>
using namespace std;
struct Test {
int MyCopy{myRef};
int& myRef{myNumber};
int myNumber{50};
};
int main()
{
Test myTest;
cout << myTest.MyCopy << endl;
return 0;
}
Why is the compiler not throwing any warning about the problem? Enabled all possible warning levels in g++ (-Wall -Weffc++ -Wextra). Can the compiler not recognise the problem?

Related

C++ did not generate warning

I had a simple typo in my code. I wanted to do const std::string a = b + "bar"; but instead accidentally had const std::string a = a + "bar"; To my surprise, this did not generate any warnings from GCC 9.3.0 even though I compiled with -std=c++17 -Wall. Moreover, I did not get a warning for an unused variable b. How can that be? What flags should I have passed to GCC to generate at least some warning to catch this problem?
#include <string>
#include <iomanip>
#include <iostream>
namespace {
const std::string b = "foo";
const std::string a = a + "bar";
}
int main()
{
std::cout << "a is " << std::quoted(a) << std::endl;
return 0;
}
The way you are using the variable a, it has an indeterminate value that is either a trap representation or a unspecified value. It can in some cases(implementation) cause undefined behavior.
GCC 11.1.0 does generate warning it seems as seen here
#include <string>
#include <iomanip>
#include <iostream>
int main()
{
int a = a + 1;//this generates warning in gcc 11.1.0
std::string p = p + "some string";//this also generate warning in gcc 11.1.0
return 0;
}
But GCC 9.3.0 only gives warning for int as seen here
On the other hand clang gives warning for both.

How does this compile if std::pow is not allowed to be constexpr for compatibility with setting things like errno?

The following C++ snippet runs and compiles fine on, for example, the below platform (not sure which compiler is used under the hood). But aren't array sizes required to be known at compile time?
https://onlinegdb.com/H1qovLHGV
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int foo[(int) std::pow(3, 5)];
foo[2] = 0;
cout<<"Hello World " << foo[2] << endl;
return 0;
}

Why is there not any warning on a declaration without initialization in a for loop?

I tried to compile the following code using g++ (gcc version 4.8.2 (Debian 4.8.2-1)), with -Wall flag (adding the -Wextra flag does not change anything for me).
#include <iostream>
using namespace std ;
int main() {
int i ;
cout << i << endl ;
}
It gave this warning:
test.cpp: In function ‘int main()’:
test.cpp:7:13: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
cout << i << endl ;
But the following code does not yield any warning:
#include <iostream>
using namespace std ;
int main() {
for(int i ; i < 10 ; i++) {
cout << i << endl ;
}
}
I did further tests.
The following yields the warning:
#include <iostream>
using namespace std ;
int main() {
int i ;
while(i<10) {
cout << i << endl ;
}
}
But the following does not:
#include <iostream>
using namespace std ;
int main() {
int i ;
while(i<10) {
cout << i << endl ;
i++ ;
}
}
In the above program, if I replace the while by an if, then I have a warning.
Is there some explanation to this? Why can the compiler recognize the problem in some cases and not in others, although they seem very close?
Thanks to Pradhan who gave this link, I understood the problem.
This link states the following:
GCC has the ability to warn the user about using the value of a uninitialized variable. Such value is undefined and it is never useful. It is not even useful as a random value, since it rarely is a random value. Unfortunately, detecting when the use of an uninitialized variable is equivalent, in the general case, to solving the halting problem. GCC tries to detect some instances by using the information gathered by optimisers and warns about them when the option -Wuninitialized is given in the command line. There are a number of perceived shortcomings in current implementation. First, it only works when optimisation is enabled through -O1, -O2 or -O3. Second, the set of false positives or negatives varies according to the optimisations enabled. This also causes high variability of the warnings reported when optimisations are added or modified between releases.
Indeed, when I add one of these flags, the compiler yields the warning.

Eclipse c++11 // vector

This is really driving me crazy:
#include <iostream>
#include <vector>
#include <string.h>
#include <thread>
using namespace std;
void test() {
vector<string> myvector;
string a("Teststring");
myvector.push_back(a);
cout << myvector.begin()->length() << endl;
}
int main() {
thread(test).join();
return 0;
}
The code compiles fine with the -std=c++11 flag to the compiler and the -pthread flag to the linker.
BUT: Eclipse does either know the std::thread or the myvector.begin()->length(), even if the code runs fine eclipse warns me "Method 'length' could not be resolved".
I tried every possible solution in here: Eclipse CDT C++11/C++0x support without any success. This took me so many hours now, what am I doing wrong?!
Is there anybody getting a project setup without problems with this code?
EDIT: Other code example - same problem:
#include <iostream>
#include <vector>
#include <thread>
using namespace std;
class TestClass {
public:
void test() {
cout << "test" << endl;
}
};
void test() {
vector<TestClass> testClassVector;
TestClass x;
testClassVector.push_back(x);
testClassVector.begin()->test();
}
int main() {
thread(test).join();
return 0;
}
Compiles and runs correct, but returns in eclipse: Method 'test' could not be resolved
EDIT:
working versions:
((TestClass)*(testClassVector.begin())).test();
TestClass foo2 = *(testClassVector.begin());
foo2.test();
still not working:
testClassVector.begin()->test();
The last compiles and works like the two above, but eclipse still claims:
Method 'test' could not be resolved
Maybe I'm wrong, but I think your problem don't come from Eclypse. Juste, begin() on a vector return a std::vector<T>::iterator first, this is not a pointer and there is no method length, but you can ask for the vector size with myvector.size(); if this is what you want.
The problem could come from your #include <string.h> that is not the same as #include <string>, string.h is for string operation like strcmp, strstr, etc... juste string will define the std::string object.
I don't have Eclipse set up but the problem appears to be around std::string. Does the problem go away if you remove the threading from the example? (I also changed to #include <string> instead of string.h)
#include <iostream>
#include <vector>
#include <string>
#include <thread>
using namespace std;
#if 0
void test() {
vector<string> myvector;
string a("Teststring");
myvector.push_back(a);
cout << myvector.begin()->length() << endl;
}
#endif
int main() {
//thread(test).join();
vector<string> myvector;
string a("Teststring");
myvector.push_back(a);
cout << myvector.begin()->length() << endl;
return 0;
}
That should hopefully print out 10.
Update from comment:
Does this generate the Eclipse warning?
auto tmp = *(myvector.begin());
std::cout << tmp.length() << std::endl;
What about this?
std::string foo("abc123");
std::cout << foo.length() << std::endl;
I guess one more too:
std::string foo2 = *(myvector.begin());
std::cout << foo2.length() << std::endl;
The solution found:
I downloaded eclipse kepler Kepler
Created a new project and tried to compile this source code (like above):
#include <iostream>
#include <vector>
#include <thread>
using namespace std;
class TestClass {
public:
void test() {
cout << "test" << endl;
}
};
void test() {
vector<TestClass> testClassVector;
TestClass x;
testClassVector.push_back(x);
testClassVector.begin()->test();
}
int main() {
thread(test).join();
return 0;
}
On the first run eclipse told me, thread belongs to the new c++11 standard and I have to add -std=c++11 to the compiler flags. To use thread I also added -pthread to the linker flags. With this steps the code could be compiled, but eclipse marks the thread still as unknown. To fix this I proceeded the following step:
Under C/C++ Build (at project settings), find the Preprocessor Include Path and go to the Providers Tab. Deselect all except CDT GCC Builtin Compiler Settings. Then untag Share settings entries … . Add the option -std=c++11 to the text box called Command to get compiler specs.
Found here.
Now - unbelievable but true - it works, even without any errors marked by eclipse. The solution is using the (beta) version of eclipse, wich seems to handle this in a better way.
Thanks for all your help!

Why do statements after return change the return value?

C++ returns invalid value in the following code:
#include <iostream>
#include <vector>
using namespace std;
int f(){
vector< int * > v[2];
return 1;
v[1].push_back(NULL);
}
int main(){
cout << f();
}
The output is:
205960
When I commnet line after return, it works fine:
#include <iostream>
#include <vector>
using namespace std;
int f(){
vector< int * > v[2];
return 1;
//v[1].push_back(NULL);
}
int main(){
cout << f();
}
The output is:
1
I am using code::blocks with mingw32-g++.exe compiler. The mingw version is: gcc version 4.4.1 (TDM-2 mingw32).
Your compiler has a bug. Fortunately, it is also obsolete. You should upgrade — G++ is up to version 4.6.2, which also implements much of C++11, which is very useful.
If you choose to stick with an older compiler, that is also a decision to accept its flaws.
Edit: If you are really stuck with 4.4 (for example due to a PHB), that series is still maintained. You can upgrade to GCC 4.4.6, released just this past April.