05-05-2016 07:17 AM
The latest CVI 2015 complains about the usage of some "possible uninitialized" variables.
I've been able to extract a little portion of code which produces the warning "variable 'aux[j]' may be uninitialized when used here".
The code is part of a sorting routine I downloaded from the web years ago and I'm not sure that the warning is correct.
int aux[4], a[4]={1,2,3,4}; int i, j, k, left=0, center=0, right=1; for (i = center+1; i > left; i--) aux[i-1] = a[i-1]; /* this initializes aux[0] */ for (j = center; j < right; j++) aux[right+center-j] = a[j+1]; /* this initializes aux[1] */ for (k = left; k <= right; k++) { if (aux[j] < aux[i]) a[k] = aux[j--]; /* the if() compares aux[0] and aux[1]. Both of them seems initialized... */ else a[k] = aux[i++]; }
The warning is on the line if (aux[j] < aux[i]) but based on the above lines I think that both of the variables are initialized.
But maybe the routine is written in a bad way and it's better to rewrite it.
Could someone help me analyzing this warning to check if it is correct (and so I need to rewrite the routine) or not?
Solved! Go to Solution.
05-07-2016 07:55 AM
What is the harm in just initialising the variable when you declare it: aux[4]={0} ?
05-09-2016 01:03 AM
If I declare declare it: aux[4]={0} I don't have the warning anymore.
Can you explain why?
Thanks
05-09-2016 03:46 PM
I have absolutely no idea. I am not a compiler expert, and do not know the inner workings of Clang. I did some simple experiments, declaring left, centre and right as const, and setting the optimization level to 3 to see if that prompted the compiler to analyse the code any better. It made no difference whatsoever, and I come to the conclusion that the uninitialized variable detection algorithm is pretty simple minded.
05-31-2016 12:02 AM - edited 05-31-2016 12:04 AM
Hi,
Sorry for being a little late.
The compiler is actually being clever when it is giving the warning.
The reason is not because it is thinking simple. It actually has thought it through.
About the first 2 for loops, which -you think- initialized aux[4]; beware that they may not get executed!
The looping condition is tested for even the first iteration. There is no guarantee that i > left and j < right.
Even if they execute, still the compiler cannot be sure the that those for loops initialize each and every one of the members of aux.
Initializing to 0 explicitly removes all those question marks.
Maybe the compiler is not so dumm after all, is it? 😉
Hope this helps,
05-31-2016 12:35 AM
First of all, thank you for your contribute to this topic.
I'm not 100% convinced about your explanation:
My real code is a little bit complicated and you explanation is probably correct.
But I created this "dummy code" by purpose, to see if the behavior of the compiler would have changed or not
05-31-2016 08:31 AM
Do you expect a compiler to make an "internal dry run" of your code and decide if all of your loops are entered and keep track of the members of the arrays which are initialized, which are not?
Think about multi-thread applications etc.. This would be a useless effort for the compiler to begin with.
Yours may be a simple dummy code but this is not upon the compiler to decide.
So the compiler has to be straightforward.
If the variable initialization is in a conditionally executed block, it is considered potentially uninitialized.
I did not try it but the conditions may be evaluated offline only if the variables are marked "const".