Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

this compiles without a warning in VC9 at warning level 4. Why would one NOT consider this a compiler defect?

I saw some posted code with an out of range error on SO that made me wonder. I would expect a compiler to generate a warning (at the highest level at least) for this code

#pragma warning(push,4)
int main(){
    int x[2];
    x[2]=0;     
    return 0;
}
#pragma warning(pop)

but it does not.

The EDG compiler nicely says:

"sourceFile.cpp", line 3: warning:
          subscript out of range
          x[2]=0;
          ^

Actually EDG says bit more more(all of which are expected)

"sourceFile.cpp", line 1: warning: 
          unrecognized #pragma
  #pragma warning(push,4)
          ^

"sourceFile.cpp", line 4: warning: 
          subscript out of range
      x[2]=0;     
      ^

"sourceFile.cpp", line 3: warning: 
          variable "x" was set but never used
      int x[2];
          ^

"sourceFile.cpp", line 7: warning: 
          unrecognized #pragma
  #pragma warning(pop)

but that's not my question.

I consider this failure to warn a SERIOUS error of omission in VC9,(even more so since an auto variable!!!!). Can anyone give me a serious reason to change my mind?

like image 233
pgast Avatar asked Nov 26 '22 23:11

pgast


1 Answers

Many compilers have options to error out this kind of thing.

But it's quite traditional and even proper for C compilers to let this go by default. There are multiple reasons for this.

  1. Remember that x[i] and i[x] are the same thing in C. You can even do "string"[2] OR you can do 2["string"] and get the same result. Try it. And this is because x[i] is defined as *(x + i) and once C is just doing pointer arithmetic and then derefing the result of the expression it's not in the compiler's domain to decide that it's going to work or not.

  2. Given that pointer arithmetic is legal, lots of fairly-decent-for-their-day design patterns actually depend on technical subscript violations

    struct s {
        ...bunch of stuff...
        int points[1]; // not really [1]
    };
    ...
    struct s *p = malloc(sizeof (struct s) + someNumber * sizeof(int));
    

    There is code like this running today all over the place...    Update: heh, here is an actual example of the struct hack on stackoverflow.

like image 192
DigitalRoss Avatar answered May 16 '23 09:05

DigitalRoss