skyking
skyking

Reputation: 14400

Why doesn't valgrind complain when copying uninitialized data?

According to the manual it doesn't:

It is important to understand that your program can copy around junk (uninitialised) data as much as it likes. Memcheck observes this and keeps track of the data, but does not complain. A complaint is issued only when your program attempts to make use of uninitialised data in a way that might affect your program's externally-visible behaviour.

The question is if there's some important reason to behave this way? Is there a (commonly) used construct that's copies uninitialized data that would trigger false positives? Or is there a way to make valgrind complain about this?

My concern was that in C the use of uninitialized variables have undefined behavior (IIRC), so for example the following functions could emit nasal daemons:

int fubar(void) {
     int a;

     return a;
}

now I recalled incorrectly, it's only in certain situations it's undefined, for example if you're doing arithmetics with uninitialized variables:

int fubar(void) {
    int a;

    a -= a;
    return a;
}

So the same question arises here. Is there some important reason for valgrind to allow arithmetics with uninitialized data? etc. Note that especially if it were floating point data it could actually alter externally observable behaviour as trapping on FP-errors might be enabled.

Upvotes: 1

Views: 772

Answers (1)

Ctx
Ctx

Reputation: 18420

Yes, this happens quite often. For example:

struct {
    char a;
    int b;
} s1, s2;

s1.a = '.';
s1.b = 31337;

memcpy (&s2, &s1, sizeof(s1));

Here, you are copying uninitialized bytes (the padding bytes between a and b).

I think, it is good that valgrind doesn't complain here.

Generally spoken (in response to your arithmetic example):

Valgrind tries to only complain when uninitialized data can be the cause of non-deterministic behaviour of your program. Or the other way round: It does not complain, if it can rule out that this is the case. So, for example, when a branch or syscall parameter depends on uninitialized data valgrind complains. You can try that out by putting exit(a) after a -= a;, which results in

Syscall param exit_group(status) contains uninitialised byte(s)

even when usually the result will be 0 in any case. (You might have to declare a volatile to prevent removing it from the code)

Upvotes: 3

Related Questions