4 ms·
It's disappointing that SPEC refuses to fix the code and is spreading disinformation like "it is at minimum arguable that the code fragment is compliant under t
by jedbrown 14y ago
It's disappointing that SPEC refuses to fix the code and is spreading disinformation like "it is at minimum arguable that the code fragment is compliant under the C89 standard". If the global 'int d[16]' is placed at the very end of a page (which the linker is allowed to do), that code compiled in the most naive possible way will SEGV.
- cygx 14y agoI wonder where their delusion that C89 allows reading past the end of an array comes from...
- mikeash 14y agoI can only guess that it comes from the fact that it's legal to have a pointer that points on element past the end of the array. That is, this is legal: int array[16]; int *ptr = array + 16; But it's not legal to actually dereference this pointer. The distinction is confusing to a lot of programmers, used to modern architectures where pointers and integers share registers and you can do crazy things with your pointer variables with no consequences. However, some architectures will crash just for having a bad pointer value. That is, this is not legal: int array[16]; int *ptr = array + 17; Even if you never dereference ptr, this code is still illegal, and the compiler is within its rights to generate code that crashes or makes demons fly out of your nose when it encounters this source. The first case is an exception made to make it easier to iterate over an array. So there's a spot in the C standard that says, essentially, "It is OK to have a pointer that points one element past the end of an array." This is probably not too hard to misread as "It is OK to read one element past the end of an array." Although that is definitely wrong.
- mnarayan01 14y agoUnless the C89 standard says something about VM interaction (I'm too lazy to check), it seems like your complaint is misguided.
- cygx 14y agoHow so? The pointer pointing past the last member of an array may not be dereferenced. Doing so is UB - end of story.
- mnarayan01 14y agoAs I said, I'm to lazy too delve into the C89 spec (and too young to have actually programmed in the pre-VM days), but my (only slightly) educated guess is that on the type of machine/OS C89 would have been targeted at, any exceptions thrown by reading past the end of an array could be solved by adding more memory; the same solution as would be required if the array was increased in size.
- mikeash 14y agoYou have it backwards. Unless the C89 standard describes behavior for this scenario, it's illegal. The business with putting the array at the end of a page is just an example of how "illegal" can translate into "crashes" on a real-world system.
- mnarayan01 14y agoIt's certainly not "illegal", it's merely undefined. This may be a pedantic difference but we're talking about an area where being technically correct _really_ is the best kind of correct. I bring up VM behavior because, particularly given the timeframe, it's important to consider that there once was a time when VM did not exist, and SEGV meant an actual _segmentation_ fault.
- mikeash 14y agoThe code in question is not valid C code. It just happens not to require an error to be raised, but I think "illegal" sums it up just fine. That's not really a specific term in this situation. As for VM and not-VM, I don't really see why it matters. It would be perfectly valid for a C compiler to generate code that does bounds checking on every array access, for example. And there were far weirder ways to do memory hardware than the standard MMU with 4kB pages that we have today, and the legacy of that can be found throughout the C standard. For example, the fact that it's illegal to store many values in a pointer, not dereference but merely store, comes from systems that really would check that stuff and crash your app if you had a bad pointer value in the wrong place, even if you didn't try to load what it pointed to.