Can g++ fill uninitialized POD variables with known values? - c++

I know that Visual Studio under debugging options will fill memory with a known value.
Does g++ (any version, but gcc 4.1.2 is most interesting) have any options that would
fill an uninitialized local POD structure with recognizable values?
struct something{ int a; int b; };
void foo() {
something uninitialized;
bar(uninitialized.b);
}
I expect uninitialized.b to be unpredictable randomness; clearly a bug and easily
found if optimization and warnings are turned on. But compiled with -g only, no
warning. A colleague had a case where code similar to this worked because it
coincidentally had a valid value; when the compiler upgraded, it started failing.
He thought it was because the new compiler was inserting known values into the structure
(much the way that VS fills 0xCC). In my own experience, it was just different
random values that didn't happen to be valid.
But now I'm curious -- is there any setting of g++ that would make it fill
memory that the standard would otherwise say should be uninitialized?

Any C++ comiler can initialize any POD type to its "zero" value using the syntax:
int i = int();
float f = float();
MyStruct mys = MyStruct();
// and generally:
T t = T();
If you want to talk about debugging that's something else...
(By the way, I think VS had all uninitialized memory initialized to 0xCC when in "debug mode, so that no matter where you jump (e.g. call a bad function pointer) that's doesn't happen to be actual program code/data int3 is raised.)

I don't think such option/feature exists in gcc/g++.
For instance, all global (and static) variables reside in the .bss section, which is always initialised to zeroes. However, uninitialised ones are put in a special section within the .bss, for sake of compatibility.
If you want the them to be zeroed too, you can pass -fno-common argument to the compiler. Or, if you need it on a per-variable basis, use __attribute__ ((nocommon)).
For heap, it's possible to write your own allocator to accomplish what you described. But for stack, I don't think there's an easy solution.

I don't believe g++ will detect all cases like this, but Valgrind certainly will.

Related

Does this self-assignment do something sensible?

I just found this line of code within a function, which puzzles me. Can this make sense in any context or it is undefined behavior?
char * acFilename = acFilename;
EDIT: The compiler complains with Warning C4700, that I am using an uninitialized variable.
At block scope, in C++, this is undefined behaviour, as the right-hand side reads the variable the variable before it has been initialized (C++14 [dcl.init]/12).
At block scope, in C11, this could either be undefined behaviour or behave as an uninitialized variable, depending on various details of the implementation and the rest of the function, see here for detailed analysis.
At namespace scope, in C++, it is OK well-defined and makes a null pointer. This is because all static variables are zero-initialized before their initializers are considered. (C++14 [basic.start.init]/2).
At file scope in C, it is a constraint violation; static variables must have a constant expression as initializer, and the value of a variable cannot be a constant expression.
No this code does not make any sense. It's probably a typo, maybe somebody meant to use
char* acFilename = ::acFilename;
or
char* acFilename = m_acFilename;
or something else.
As it stands, it's confusing and unhelpful at best, probably a bug because somebody meant to use a different variable.
I've seen this before. Since gcc is quite trigger happy with its uninitialized variable warnings this is a trick to silence those warnings. Not sure if it's intentional design choice by gcc or the compiler just being stupid, but I've seen people do this on purpose to make gcc shut up (and in the process break the warning that might be correct in the future).
I would just replace it with an initialization to NULL. This is a bad habit, doesn't work on other compilers and a NULL can't be less correct than an indeterminate value and undefined behavior.
Just to demonstrate how this works (and also because I wanted to know if newer gcc versions still do this):
$ cat foo.c
int
foobar(void)
{
int foo;
return foo + foo;
}
$ cc -c -Wall -O2 foo.c
foo.c: In function ‘foobar’:
foo.c:6:13: warning: ‘foo’ is used uninitialized in this function [-Wuninitialized]
return foo + foo;
~~~~^~~~~
$ ed foo.c
[...]
$ cc -c -Wall -O2 foo.c
$ cat foo.c
int
foobar(void)
{
int foo = foo;
return foo + foo;
}
$ cc -c -Wall -O2 foo.c
$ cc -v
[...]
gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12)
$
At some locations within a program, it may be possible for a variable to be in either of the following conditions:
Inputs that have been received have caused the variable to be written, and will also cause code to use its value in future.
Inputs that have been received have caused the variable not to be written, but will also cause code not to make any use of its value.
Some compilers will squawk if they see that there exist inputs which would cause a variable to not to get written, and there exist inputs which would cause the variable to be read. Even if the only input which would cause the variable to get read would also cause it to get written, the compilers may not realize that. While it would be possible to silence the compiler's complaints by unconditionally initializing the variable, machine code which initializes the variable with a value which can never actually get used would serve no functional purpose. A source code construct which would silence the compiler's complaints but not result in the compiler generating useless machine code may thus be preferable to one which would need to generate useless machine code. On some compilers, a self-initializing declaration may serve such a purpose.
If a type has trap representations, there may be no practical alternative to writing an initialization that a compiler will likely turn into useless machine code, but if a type doesn't have trap representations there is no particular reason why a quality compiler should force programmers to ask for useless code they don't want and don't need. Rather than try to have different rules for platforms where various types do and don't have trap representations, however, the authors of the Standard defer to implementers' judgments as to what sorts of behavior would be sensible on for a particular target platform and application field.
If on some platform a compiler couldn't allow programmers to omit initialization for variables which are copied but otherwise unused without having to generate likely-redundant initializations itself, it would make sense to require the programmer to include initializations in all situations that could actually occur. On another platform where copying a meaningless value would simply cause the destination to hold a meaningless value, however, it would generally make more sense to allow a programmer to omit initialization in cases where none of the copies would ever end up getting used for any real purpose. The authors of the Standard make no effort to specify what would make sense in any particular case, because they expect that people writing implementations should be capable of exercising good judgment.
The best approach for dealing with this situation would probably be to write a macro which accepts a variable, and whose expansion will initialize the variable to zero (for implementations whose authors judge that there is more value in allowing the compilers to jump the rails when an uninitialized variable is copied, even if none of the copies are really "used" for anything, than there would be in guaranteeing that the mere act of copying a variable will have no side-effects) or else do nothing (when using an implementation which will stay on the rails even without the useless initialization).

Why aren't gcc-compiled programs sefaulting on dereferencing an uninitialized pointer in a Debug build? [duplicate]

I know that Visual Studio under debugging options will fill memory with a known value.
Does g++ (any version, but gcc 4.1.2 is most interesting) have any options that would
fill an uninitialized local POD structure with recognizable values?
struct something{ int a; int b; };
void foo() {
something uninitialized;
bar(uninitialized.b);
}
I expect uninitialized.b to be unpredictable randomness; clearly a bug and easily
found if optimization and warnings are turned on. But compiled with -g only, no
warning. A colleague had a case where code similar to this worked because it
coincidentally had a valid value; when the compiler upgraded, it started failing.
He thought it was because the new compiler was inserting known values into the structure
(much the way that VS fills 0xCC). In my own experience, it was just different
random values that didn't happen to be valid.
But now I'm curious -- is there any setting of g++ that would make it fill
memory that the standard would otherwise say should be uninitialized?
Any C++ comiler can initialize any POD type to its "zero" value using the syntax:
int i = int();
float f = float();
MyStruct mys = MyStruct();
// and generally:
T t = T();
If you want to talk about debugging that's something else...
(By the way, I think VS had all uninitialized memory initialized to 0xCC when in "debug mode, so that no matter where you jump (e.g. call a bad function pointer) that's doesn't happen to be actual program code/data int3 is raised.)
I don't think such option/feature exists in gcc/g++.
For instance, all global (and static) variables reside in the .bss section, which is always initialised to zeroes. However, uninitialised ones are put in a special section within the .bss, for sake of compatibility.
If you want the them to be zeroed too, you can pass -fno-common argument to the compiler. Or, if you need it on a per-variable basis, use __attribute__ ((nocommon)).
For heap, it's possible to write your own allocator to accomplish what you described. But for stack, I don't think there's an easy solution.
I don't believe g++ will detect all cases like this, but Valgrind certainly will.

Why C++ compiler isn't optimizing unused reference variables?

Consider following program:
#include <iostream>
struct Test
{
int& ref1;
int& ref2;
int& ref3;
};
int main()
{
std::cout<<sizeof(Test)<<'\n';
}
I know that C++ compiler can optimize the reference variables entirely so that they won't take any space in memory at all.
I tested a above demo program to see the output.
But when I compile & run on g++ 4.8.1 it gives me output 12.
It looks like compiler isn't optimizing the reference variables. I was expecting size of the Test struct to be 1.
I've also used -Os command line option but it still gives me output 12. I have also tried this program on MSVS 2010
compiled with /Ox command line option but it looks like Microsoft compiler isn't performing any optimization at all.
The three reference variables are unused & they aren't associated with any other variable. Then why compilers aren't optimizing them?
The size of the struct stays the same, there is nothing to optimize. If you would like to create an array of Test it should allocate the right size for each Test. The compiler cannot know which will be used or not. That's why there is no such optimization.
Unused variables would be for example a new int& int inside your main function. If this is unused, the optimizer will optimize it away.
Theoretically, if the world would only consist of simple programs, the compiler could optimize the sizeof of this struct to 1, because the sizeof of a struct is unspecified.
But in our real world, we have separate compilation of shared libraries that the compiler when compiling your code has no clue about (for example you could LoadLibrary or dlopen) that also happen to define your struct and where the sizeof should better agree with that in your program.
So actually a compiler better doesn't opimize the sizeof to 1 :)
In 8.3.2.4, of the C++ standard, it is said
It is unspecified whether or not a reference requires storage
So, the standard leaves it open to the implementation how references should be implemented. This implies that the size of your struct can be non-zero.
If the compiler would remove the references from the struct, you would not be able to link code compiled with different compiler settings. Imagine you compile one translation unit with optimizations, the other one without and link them together and pass an object from one TU to the other. Which size should the code assume? A function in TU 1 allocates 12 bytes on the stack, while a function in TU 2 allocates some other space.
The compiler can optimize your program and e.g. remove temporary objects, assignments etc. It may that you create an object of your struct somewhere in your source code and use it, but it will not be seen in the assembler code because it is not needed. What compilers also frequently do is remove indirections, e.g. by replacing references with direct access.

G++ 4.4 "uninitialized" variables

I am using g++ on Ubuntu 10.10(64-bit) if the OS is at all relevant for the matter.
I saw something strange so i decided to check and for some reason this code
#include <iostream>
int main()
{
int a;
std::cout << a << std::endl;
return 0;
}
always prints 0. Obviously g++ does auto initialization of uninitialized variables to their corresponding null-value. The thing is I want to turn that feature off, or at least make g++ show warning about using uninitialized variables, since this way my code won't work well when compiled on VS for instance. Besides I'm pretty sure the C++ standard states that a variable which isn't implicitly initialized with some value has an undefined value amongst all it's possible values, which should in fact be different with every execution of the program, since different parts of the operating memory are used every time it's executed.
Explicit question: Is there a way to make g++ show warnings for uninitialized variables?
GCC does not initialize uninitialized variables to 0. It's just a case that a is 0.
If what you want to do is to receive warnings when you use uninitialized variables you could use GCC option -Wuninitialized (also included by -Wall).
However it can't statically spot any possible usage of uninitialized variables: you'll need some run time tools to spot that, and there's valgrind for this.
You might also try to use a tool like cppcheck. In general, in well written C++ there is rarely a reason to declare a variable without initializing it.

Why is it that an int in C++ that isnt initialized (then used) doesn't return an error?

I am new to C++ (just starting). I come from a Java background and I was trying out the following piece of code that would sum the numbers between 1 and 10 (inclusive) and then print out the sum:
/*
* File: main.cpp
* Author: omarestrella
*
* Created on June 7, 2010, 8:02 PM
*/
#include <cstdlib>
#include <iostream>
using namespace std;
int main() {
int sum;
for(int x = 1; x <= 10; x++) {
sum += x;
}
cout << "The sum is: " << sum << endl;
return 0;
}
When I ran it it kept printing 32822 for the sum. I knew the answer was supposed to be 55 and realized that its print the max value for a short (32767) plus 55. Changing
int sum;
to
int sum = 0;
would work (as it should, since the variable needs to be initialized!). Why does this behavior happen, though? Why doesnt the compiler warn you about something like this? I know Java screams at you when something isnt initialized.
Thank you.
Edit:
Im using g++. Here is the output from g++ --version:
Im on Mac OS X and am using g++.
nom24837c:~ omarestrella$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646)
Reading from an uninitialized variable results in undefined behavior and the compiler isn't required to diagnose the error.
Note that most modern compilers will warn you if you attempt to read an uninitialized variable. With gcc you can use the -Wuninitialized flag to enable that warning; Visual C++ will warn even at warning level 1.
Because it's not part of the C++ standard. The variable will just take whatever value is currently sitting in the memory it's assigned. This saves operations which can sometimes be unnecessary because the variable will be assigned a value later.
It's interesting to note and very important for Java/.Net programmers to note when switching to C/C++. A program written in C++ is native and machine-level. It is not running on a VM or a some other sort of framework. It is a collection of raw operations (for the most part). You do not have a virtual machine running in the background checking you variables and catching exceptions or segfaults for you. This is a big difference which can lead to a lot of confusion in the way C++ handles variables and memory, as opposed to Java or a .Net language. Hell, in .Net all your integers are implicitly initialised to 0!
Consider this code fragment:
int x;
if ( some_complicated_condition ) {
x = foo;
} else if ( another_condition ) {
// ...
if ( yet_another_condition ) x = bar;
} else {
return;
}
printf("%d\n",x);
Is x used uninitialized? How do you know? What if there are preconditions to the code?
These are hard questions to answer automatically, and enforcing initialization might be inefficient in some small way.
In point of fact modern compilers do a pretty good job of static analysis and can often tell if a variable is or might be used uninitialized, and they generally warn you in that case (at least if you turn the warning level up high enough). But c++ follows closely on the c tradition of expecting the programmer to know what he or she is doing.
It's how the spec is defined--that uninitialized variables have no guarantee's, and I believe the reason is that it has to do with optimizations (though I may be wrong here...)
Many compilers will warn you, depending on the warning level used. I know by default VC++ 2010 warns for this case.
What compiler are you using? There is surely a warning level you can turn on via command-line switch that would warn you of this. Try compiling with /W3 or /W4 on Windows and you'll get 4700 or 6001.
This is because C++ was designed as a superset of C, to allow easy upgrading of existing code. C works that way because it dates back to the 70s when CPU cycles were rare and precious things, so weren't wasted initialising variables when it might not be necessary (also, programmers were trusted to know that they'd have to do it themselves).
Obviously that wasn't really the case once Java appeared, so they found it a better tradeoff to spend a few CPU cycles to avoid that class of bugs. As others have noted though, modern C or C++ compilers will normally have warnings for this kind of thing.
Because C developers care about speed. Uselessly initializing a variable is a crime against performance.
Detecting an uninitialized variable is a Quality-of-Implementation (QoI) issue. It is not mandatory, since the language standard does not require it.
Most compilers I know will actually warn you about the potential problem with an initialized variable at compile-time. On top of that, compilers like MS Visual Studio 2005 will actually trap the use of an uninitialized variable during run-time in debug builds.
So, what compiler are you using?
Well, it depends on what compiler you use. Use a smart one. :)
http://msdn.microsoft.com/en-us/library/axhfhh6x.aspx
Initialising variables is one of the most important tenets of C/C++. Any types without a constructor should be initialised, period. The reason for compiler not enforcing this is largely historical. It stems from the fact sometimes it's not necessary to init something and it would be wasteful to do so.
These days this sort of optimisation is best left to compiler and it's a good habit to always initialise everything. You can get the compiler to generate a warning for you as others suggested. Also you can make it treat warnings as errors to further simulate javac behaviour.
C++ is not a pure object oriented programming language.
In C++ there is no implicit way of memory management and variable initialization.
If a variable is not initialized in C++ then it may take any value at runtime because the compiler does not understand such internal errors in C++.