[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: const pains with lpcode in Lpeg 0.11
- From: Philipp Janda <siffiejoe@...>
- Date: Sat, 30 Mar 2013 14:04:11 +0100
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