const pains with lpcode in Lpeg 0.11

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

const pains with lpcode in Lpeg 0.11

Gavin Wraith
I am having these error messages when I try to compile
lpeg 0.11:

"c.lpcode", line 287: Error: assignment to 'const' object 'follow'
"c.lpcode", line 287: Error: '=': qualifier-losing implicit cast of pointer
"c.lpcode", line 444: Warning: <argument 2 to 'addinstruction'>: cast of 'int' to differing enum
"c.lpcode", line 511: Warning: <argument 2 to 'addinstruction'>: cast of 'int' to differing enum
"c.lpcode", line 565: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 584: Error: <argument 2 to 'getfirst'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 600: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 608: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 626: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 633: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 664: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 687: Error: <argument 2 to 'getfirst'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 692: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 708: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 727: Error: <argument 2 to 'getfirst'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 734: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 778: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 802: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer
"c.lpcode", line 892: Error: <argument 5 to 'codegen'>: qualifier-losing implicit cast of pointer

which I guess happens because my compiler does not allow assignments to types qualified as
const. Any suggestions how I get round this?

--
Gavin Wraith ([hidden email])
Home page: http://www.wra1th.plus.com/

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Rob Kendrick-2
On Fri, Mar 29, 2013 at 01:15:12PM +0000, Gavin Wraith wrote:
> I am having these error messages when I try to compile
> lpeg 0.11:
>
> "c.lpcode", line 287: Error: assignment to 'const' object 'follow'
>
> which I guess happens because my compiler does not allow assignments to types qualified as
> const. Any suggestions how I get round this?

Hmm, time for a language lawyer.  At first glance, assigning to "const
charset follow" seems file, because charset is a typedef for an array of
chars.  What's changing is the the pointer, not what is pointed at, and
that would be fine.  I assume you're using Norcroft?  It may be that it
is not expanding the typedef at the correct time.

Of course, you could use GCC :)

B.

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Philipp Janda
Am 29.03.2013 14:33 schröbte Rob Kendrick:

> On Fri, Mar 29, 2013 at 01:15:12PM +0000, Gavin Wraith wrote:
>> I am having these error messages when I try to compile
>> lpeg 0.11:
>>
>> "c.lpcode", line 287: Error: assignment to 'const' object 'follow'
>>
>> which I guess happens because my compiler does not allow assignments to types qualified as
>> const. Any suggestions how I get round this?
>
> Hmm, time for a language lawyer.  At first glance, assigning to "const
> charset follow" seems file, because charset is a typedef for an array of
> chars.  What's changing is the the pointer, not what is pointed at, and
> that would be fine.  I assume you're using Norcroft?  It may be that it
> is not expanding the typedef at the correct time.
>
> Of course, you could use GCC :)

... or just #define const to nothing, which technically speaking invokes
undefined behavior IIRC, but you are obviously not in ISO-C land anyhow ...

>
> B.
>

Philipp





Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Rob Kendrick-2
In reply to this post by Rob Kendrick-2
On Fri, Mar 29, 2013 at 01:33:18PM +0000, Rob Kendrick wrote:

> On Fri, Mar 29, 2013 at 01:15:12PM +0000, Gavin Wraith wrote:
> > I am having these error messages when I try to compile
> > lpeg 0.11:
> >
> > "c.lpcode", line 287: Error: assignment to 'const' object 'follow'
> >
> > which I guess happens because my compiler does not allow assignments to types qualified as
> > const. Any suggestions how I get round this?
>
> Hmm, time for a language lawyer.  At first glance, assigning to "const
> charset follow" seems file, because charset is a typedef for an array of
> chars.  What's changing is the the pointer, not what is pointed at, and
> that would be fine.  I assume you're using Norcroft?  It may be that it
> is not expanding the typedef at the correct time.

Further to this; I tried the following:

typedef unsigned char byte;
typedef byte Charset[123];

void test(const Charset follow)
{
        follow = NULL;
}

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.

B.

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Gavin Wraith
In message <[hidden email]> you wrote:

> On Fri, Mar 29, 2013 at 01:33:18PM +0000, Rob Kendrick wrote:
> > On Fri, Mar 29, 2013 at 01:15:12PM +0000, Gavin Wraith wrote:
> > > I am having these error messages when I try to compile
> > > lpeg 0.11:
> > >
> > > "c.lpcode", line 287: Error: assignment to 'const' object 'follow'
> > > ..............

> Further to this; I tried the following:
> ..............................
>
> 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.

Thanks for this. I have now got it sorted, and version 5.60 of RiscLua
uses Lua 5.2.2 and Lpeg 0.11. I am afraid that my cleaving to Norcroft
is like Augustine of Hippo's "Lord grant me chastity and continence but
not yet".
I tried building a version with shared libraries and the SOManager but
got no success yet. I will probably switch when I do.
--
Gavin Wraith ([hidden email])
Home page: http://www.wra1th.plus.com/

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Jay Carlson
In reply to this post by Rob Kendrick-2
On Mar 29, 2013, at 11:39 AM, Rob Kendrick wrote:

> On Fri, Mar 29, 2013 at 01:33:18PM +0000, Rob Kendrick wrote:
>> On Fri, Mar 29, 2013 at 01:15:12PM +0000, Gavin Wraith wrote:
>>> I am having these error messages when I try to compile
>>> lpeg 0.11:
>>>
>>> "c.lpcode", line 287: Error: assignment to 'const' object 'follow'
>>>
>>> which I guess happens because my compiler does not allow assignments to types qualified as
>>> const. Any suggestions how I get round this?
>>
>> Hmm, time for a language lawyer.  At first glance, assigning to "const
>> charset follow" seems file, because charset is a typedef for an array of
>> chars.  What's changing is the the pointer, not what is pointed at, and
>> that would be fine.  I assume you're using Norcroft?  It may be that it
>> is not expanding the typedef at the correct time.
>
> Further to this; I tried the following:
>
> typedef unsigned char byte;
> typedef byte Charset[123];
>
> void test(const Charset follow)
> {
> follow = NULL;
> }

As with many errors, this may be revealing of internal structure.

Charset has the array-nature. Giving it a name with typedef does not hide this. Consider instead this alternate declaration:

typedef unsigned char byte;
typedef struct { byte s[123]; } Charset;

gcc will indeed blow up on "follow = NULL" because now follow is a scalar, passed and returned by value.

(Remove the const and it will next tell you that assigning an int to a struct makes no sense.)

typedefs are leaky abstractions. I guess I can live with that; C++ shows in great detail what happens once you set out to make pointer-nature and scalar-nature textually transparent.
Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Rob Kendrick-2
In reply to this post by Gavin Wraith
On Fri, Mar 29, 2013 at 04:27:34PM +0000, Gavin Wraith wrote:

> In message <[hidden email]> 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.
>
> Thanks for this. I have now got it sorted, and version 5.60 of RiscLua
> uses Lua 5.2.2 and Lpeg 0.11. I am afraid that my cleaving to Norcroft
> is like Augustine of Hippo's "Lord grant me chastity and continence but
> not yet".
> I tried building a version with shared libraries and the SOManager but
> got no success yet. I will probably switch when I do.

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.

Any other language lawyers want to chime in?  It might be worth
refactoring this code to avoid the situation all together: there are
still quite a few embedded compilers out there based on the Norcroft
frontend.

B.

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Philipp Janda
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 <[hidden email]> 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




Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Coda Highland
On Sat, Mar 30, 2013 at 6:04 AM, Philipp Janda <[hidden email]> wrote:
> 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_. [...]

What made you STOP worrying about this? It still looks completely
relevant... If you can't convert char[] to a char* lvalue, what makes
you able to assign to it?

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Owen Shepherd

The type has already been adjusted by the time of the assignment

On 30 Mar 2013 13:38, "Coda Highland" <[hidden email]> wrote:
On Sat, Mar 30, 2013 at 6:04 AM, Philipp Janda <[hidden email]> wrote:
> 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_. [...]

What made you STOP worrying about this? It still looks completely
relevant... If you can't convert char[] to a char* lvalue, what makes
you able to assign to it?

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Philipp Janda
Am 30.03.2013 15:00 schröbte Owen Shepherd:
> The type has already been adjusted by the time of the assignment

Exactly. The parameter type is adjusted, so the conversion of array type
to pointer type happens outside of the function call, and the pointer
rvalue argument is just assigned to the parameter lvalue. It's basically
the same as

void test( int i ) {
   i = 2;
}

test( 3 )

3 isn't an lvalue either, but i is.


> On 30 Mar 2013 13:38, "Coda Highland" <[hidden email]> wrote:
>
>> On Sat, Mar 30, 2013 at 6:04 AM, Philipp Janda <[hidden email]> wrote:
>>> 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_. [...]
>>
>> What made you STOP worrying about this? It still looks completely
>> relevant... If you can't convert char[] to a char* lvalue, what makes
>> you able to assign to it?
>>
>> /s/ Adam
>>
>>



Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Roberto Ierusalimschy
In reply to this post by Rob Kendrick-2
> Any other language lawyers want to chime in?  It might be worth
> refactoring this code to avoid the situation all together: there are
> still quite a few embedded compilers out there based on the Norcroft
> frontend.

I will refactor it; probably I will enclose the array inside a structure.
We should avoid code that needs language lawyers, and "arrays as types"
is a stange beast in C.

-- Roberto

Reply | Threaded
Open this post in threaded view
|

Re: const pains with lpcode in Lpeg 0.11

Roberto Ierusalimschy
In reply to this post by Gavin Wraith
> I am having these error messages when I try to compile
> lpeg 0.11:

Have lpeg 0.12 corrected these messages?

-- Roberto