I have a request for NVCC to throw an error or warning in the following case (2.2 beta does not):
__device__ void testkernel()
{
__shared__ float variable;
if (threadIdx.x==0) {
//some code
float variable = 1.0f;
//much more code
variable = some_calculated_thing; //Here I thought I was allocating the __shared__ variable.
}
__syncthreads();
//variable is 0.0f here (at least in all threads with theadIdx.x!=0)
}
It has caused me to loose another bunch of already gray hairs over the last few days (and I don’t have that many to spare).
Theoretically, I’d have expected you would get a warning along the lines of “local variable ‘variable’ is referenced, but never set.”.
If you didn’t get such a warning, yes - nvcc needs to be improved (sounds like a bug in the AST parsing, thinking that the function level ‘variable’ is the same as the condition level ‘variable’).
It is standard for variables in an inner scope to hide variables in an outer scope.
For example:
int foo = 1;
{
int foo = 3;
printf("foo is %d\n", foo);
}
printf("foo is %d\n", foo);
produces the output:
foo is 3
foo is 1
I know it really gets confusing when multiple variables are permitted go by the same name, but the complaint should probably be directed at the language, not at the compiler.
Yes, that’s how scope works in C/C++ - but no, the complaint shouldn’t be aimed at the language. (unless you’re complaining about the confusion of same-named variables in different scope, in general…)
Almost every compiler I’m aware of does warn about this use case, indicating the warning I said above (something along the lines of "Variable ‘x’ is referenced, but never set.') - and nvcc should be no exception, especially for ‘confusing’ cases like this.
Note: there’s a ‘very’ big difference between your code sample, and the OPs code sample (he never initialises ‘variable’ - which is equivalent to your ‘foo’), and for your case - I wouldn’t expect a warning at all (despite the fact it can be ‘confusing’), but for the OPs case - I would certainly expect a warning…
Well, it would be nice if it were possible to get a warning for ‘redefining’ a shared variable. And no, I did not get a warning for using an uninitialized variable, I can see why you would expect that, did not think about that yet.
Offcourse, in the end it is just me showing a lack of brain and suffering as a consequence ;)
An uninitialized variable warning makes sense. Although it should be very conservative and only point out the obvious cases.
As for hiding variables, in general it’s possible to hide a variable with another variable of any type. I see it as shared is part of the type. Not that an exception is out of the question. Function pointers and recursion already deviate from C.