[Cryptography] Ada vs Rust vs safer C
Ron Garret
ron at flownet.com
Sat Sep 17 19:47:30 EDT 2016
On Sep 17, 2016, at 10:11 AM, Florian Weimer <fw at deneb.enyo.de> wrote:
> * Ron Garret:
>
>> On Sep 17, 2016, at 8:55 AM, Florian Weimer <fw at deneb.enyo.de> wrote:
>>
>>>> 4. If you really REALLY want to win big, define a new language that
>>>> is just like C but where v[offset] and *(v+offset) are NOT equivalent
>>>> operations, and deprecate the latter.
>>>
>>> Existing compilers already track pointer provenance information, the
>>> syntactic separation isn't really required.
>>
>> Yes, it is. There is a significant difference between x[y] and *(x+y)
>> despite the fact that the C standard specifies that these are
>> equivalent constructs: in *(x+y) the offset calculation and
>> dereference operation are *syntactically separable*, whereas in x[y]
>> they are not. So in the case of x[y] the compiler can know that this
>> is an offset+dereference operation without having to do any analysis.
>> *(x+y) is just a special case of *(f(x,y)), and figuring out whether
>> or not that is equivalent to x[y] is uncomputable in general (it’s
>> equivalent to the halting problem).
>>
>> This fact is reflected in real systems. The following code:
>>
>> int main(int argc, char* argv[]) {
>> int x[100];
>> int y = x[101];
>> int z = *(x+101);
>> return y+z;
>> }
>>
>> generates one warning under clang, not two (and zero under gcc even with -Wall).
>
> Recent GCC generates:
>
> t.c: In function ‘main’:
> t.c:3:7: warning: ‘x[101]’ is used uninitialized in this function [-Wuninitialized]
> int y = x[101];
> ^
> t.c:4:7: warning: ‘*((void *)&x+404)’ is used uninitialized in this function [-Wuninitialized]
> int z = *(x+101);
> ^
> t.c:5:11: warning: ‘x[101]’ is used uninitialized in this function [-Wuninitialized]
> return y+z;
> ~^~
>
> Not really pretty, I admit.
>
> But if I change your example to:
>
> int main(int argc, char* argv[]) {
> int x[100] = {0};
> int y = x[101];
> int z = *(x+102);
> return y+z;
> }
>
> GCC still warns:
>
> t.c: In function ‘main’:
> t.c:3:12: warning: array subscript is above array bounds [-Warray-bounds]
> int y = x[101];
> ~^~~~~
> t.c:4:7: warning: ‘*((void *)&x+408)’ is used uninitialized in this function [-Wuninitialized]
> int z = *(x+102);
> ^
>
> So GCC tracks both expressions and knows that they are problematic
> because the subscript is out of bounds (although the GIMPLE
> representation is different). I'm not sure if the warnings are issued
> from the same pass yet.
What matters here is that you get an array bounds warning for x[101] but NOT for *(x+102)
The use-of-uninitialized-data warnings are a red herring. They have nothing to do with the point I was trying to make about the effective difference between x[y] and *(x+y).
rg
More information about the cryptography
mailing list