lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Am 30.03.2013 11:50 schröbte Rob Kendrick:
On Fri, Mar 29, 2013 at 04:27:34PM +0000, Gavin Wraith wrote:
In message <20130329153937.GE18728@pepperfish.net> you wrote:

With Norcroft:
*cc -strict -c99 -fah -Wh -Otime SSEx4nim.c
Norcroft RISC OS ARM C vsn 5.69 [20 Oct 2010]
"c.SSEx4nim", line 7: Warning: extern 'test' not declared in header
"c.SSEx4nim", line 8: Error: assignment to 'const' object 'follow'
c.SSEx4nim: 1 warning, 1 error, 0 serious errors

With GCC, clang, and lcc, there is no error.  I think this is a bug in
Norcroft.


I had somebody else take a look at this, and they have the opposing view
that the compiler is right and the code makes use of undefined behavior.
I don't have the standard to hand (I'm away from home) so it's hard to
tell.


I still think that Norcroft is wrong:

6.7.3 (Type qualifiers)
§ 8 If the specification of an array type includes any type qualifiers, the element type is so-qualified, not the array type. If the specification of a function type includes any type qualifiers, the behavior is undefined.118)

118) Both of these can occur through the use of typedefs.


6.5.2.2 (Function calls)
§ 4 An argument may be an expression of any object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.81)

81) A function may change the values of its parameters, but these changes cannot affect the values of the arguments. On the other hand, it is possible to pass a pointer to an object, and the function may change the value of the object pointed to. A parameter declared to have array or function type is adjusted to have a pointer type as described in 6.9.1.


6.9.1 (Function definitions)
§ 7   [...] In either case, the type of each parameter is adjusted as
described in 6.7.5.3 for a parameter type list; the resulting type shall be an object type.

§ 9 Each parameter has automatic storage duration. Its identifier is an lvalue, which is in effect declared at the head of the compound statement that constitutes the function body (and therefore cannot be redeclared in the function body except in an enclosed block). [...]


6.7.5.3 (Function declarators (including prototypes)
§ 7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. [...]


What had me worried for a moment was (emphasis mine)

6.3.2.1 (Lvalues, arrays, and function designators)
§ 3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object _and is not an lvalue_. [...]


Source: ISO/IEC 9899:TC3 WG14/N1256 Committee Draft


So,

    typedef unsigned char Charset[123];
    void test( const Charset follow ) { ... }

becomes

    void test( unsigned char follow[123] const ) { ... }

which becomes

    void test( unsigned char const follow[123] ) { ... }

which becomes

    void test( unsigned char const* follow ) { ... }

and the assignment should be ok.


Btw., it seems that #defining const to nothing is actually allowed.


B.


Philipp