public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Variably modified at file scope due to (void *)0 == (sem_t *)0?
@ 2018-10-04  8:51 Sebastian Huber
  2018-10-04  8:58 ` Jonathan Wakely
  0 siblings, 1 reply; 5+ messages in thread
From: Sebastian Huber @ 2018-10-04  8:51 UTC (permalink / raw)
  To: GCC help

Hello,

I use a typedef for static assertions for pre C11 compilers. For one 
static assertion

typedef struct { int i; } sem_t;

typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 1 : -1];

_Static_assert((void *)0 == (sem_t *)0, "sem_failed");

I get a warning like this:

gcc -S -o - sa.c > /dev/null
sa.c:3:1: warning: variably modified ‘static_assert_sem_failed’ at file 
scope
  typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 1 : -1];
  ^~~~~~~

Is there some way to get around this warning? The same expression in the 
_Static_assert() doen't lead to a warning.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Variably modified at file scope due to (void *)0 == (sem_t *)0?
  2018-10-04  8:51 Variably modified at file scope due to (void *)0 == (sem_t *)0? Sebastian Huber
@ 2018-10-04  8:58 ` Jonathan Wakely
  2018-10-04  9:11   ` Sebastian Huber
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2018-10-04  8:58 UTC (permalink / raw)
  To: Sebastian Huber; +Cc: gcc-help

On Thu, 4 Oct 2018 at 09:51, Sebastian Huber wrote:
>
> Hello,
>
> I use a typedef for static assertions for pre C11 compilers. For one
> static assertion
>
> typedef struct { int i; } sem_t;
>
> typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 1 : -1];
>
> _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
>
> I get a warning like this:
>
> gcc -S -o - sa.c > /dev/null
> sa.c:3:1: warning: variably modified ‘static_assert_sem_failed’ at file
> scope
>   typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 1 : -1];
>   ^~~~~~~
>
> Is there some way to get around this warning?

You could move the homemade assertion so it's not at file scope:

__attribute__((used)) static void assertions() {
  __attribute__((used)) typedef int static_assert_sem_failed [((void
*)0 == (sem_t *)0) ? 1 : -1];
}

> The same expression in the
> _Static_assert() doen't lead to a warning.

It does with -pedantic, and that makes the reason for the warning clearer:

foo.c:5:26: warning: expression in static assertion is not an integer
constant expression [-Wpedantic]
 _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
                ~~~~~~~~~~^~~~~~~~~~~~~

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Variably modified at file scope due to (void *)0 == (sem_t *)0?
  2018-10-04  8:58 ` Jonathan Wakely
@ 2018-10-04  9:11   ` Sebastian Huber
  2018-10-04 12:28     ` Liu Hao
  0 siblings, 1 reply; 5+ messages in thread
From: Sebastian Huber @ 2018-10-04  9:11 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On 04/10/2018 10:56, Jonathan Wakely wrote:
> On Thu, 4 Oct 2018 at 09:51, Sebastian Huber wrote:
>> Hello,
>>
>> I use a typedef for static assertions for pre C11 compilers. For one
>> static assertion
>>
>> typedef struct { int i; } sem_t;
>>
>> typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 1 : -1];
>>
>> _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
>>
>> I get a warning like this:
>>
>> gcc -S -o - sa.c > /dev/null
>> sa.c:3:1: warning: variably modified ‘static_assert_sem_failed’ at file
>> scope
>>    typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 1 : -1];
>>    ^~~~~~~
>>
>> Is there some way to get around this warning?
> You could move the homemade assertion so it's not at file scope:
>
> __attribute__((used)) static void assertions() {
>    __attribute__((used)) typedef int static_assert_sem_failed [((void
> *)0 == (sem_t *)0) ? 1 : -1];
> }

Thanks, this works.

>
>> The same expression in the
>> _Static_assert() doen't lead to a warning.
> It does with -pedantic, and that makes the reason for the warning clearer:
>
> foo.c:5:26: warning: expression in static assertion is not an integer
> constant expression [-Wpedantic]
>   _Static_assert((void *)0 == (sem_t *)0, "sem_failed");

This looks bad, so basically a pointer constant doesn't exist in standard C?

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Variably modified at file scope due to (void *)0 == (sem_t *)0?
  2018-10-04  9:11   ` Sebastian Huber
@ 2018-10-04 12:28     ` Liu Hao
  2018-10-05  5:51       ` Sebastian Huber
  0 siblings, 1 reply; 5+ messages in thread
From: Liu Hao @ 2018-10-04 12:28 UTC (permalink / raw)
  To: Sebastian Huber, Jonathan Wakely; +Cc: gcc-help

在 2018-10-04 17:11, Sebastian Huber 写道:
> On 04/10/2018 10:56, Jonathan Wakely wrote:
>> On Thu, 4 Oct 2018 at 09:51, Sebastian Huber wrote:
>>> Hello,
>>>
>>> I use a typedef for static assertions for pre C11 compilers. For one
>>> static assertion
>>>
>>> typedef struct { int i; } sem_t;
>>>
>>> typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 1 : 
>>> -1];
>>>
>>> _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
>>>
>>> I get a warning like this:
>>>
>>> gcc -S -o - sa.c > /dev/null
>>> sa.c:3:1: warning: variably modified ‘static_assert_sem_failed’ at file
>>> scope
>>>    typedef int static_assert_sem_failed [((void *)0 == (sem_t *)0) ? 
>>> 1 : -1];
>>>    ^~~~~~~
>>>
>>> Is there some way to get around this warning?
>> You could move the homemade assertion so it's not at file scope:
>>
>> __attribute__((used)) static void assertions() {
>>    __attribute__((used)) typedef int static_assert_sem_failed [((void
>> *)0 == (sem_t *)0) ? 1 : -1];
>> }
> 
> Thanks, this works.
> 

This works for me on GCC 4.9, 7 and 8:

```
#define FORCE_CONSTANT_TRUE(expr)  (__builtin_constant_p(expr) ? (expr) : 0)

typedef int static_assert_sem_failed [FORCE_CONSTANT_TRUE((void *)0 == 
(sem_t *)0) ? 1 : -1];
```

>>
>>> The same expression in the
>>> _Static_assert() doen't lead to a warning.
>> It does with -pedantic, and that makes the reason for the warning 
>> clearer:
>>
>> foo.c:5:26: warning: expression in static assertion is not an integer
>> constant expression [-Wpedantic]
>>   _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
> 
> This looks bad, so basically a pointer constant doesn't exist in 
> standard C?
> 

As a difference from C++, C does not allow pointer operands in an 
/integer constant expression/, despite the type of results of pointer 
comparison, which is `int`.

Because of VLAs, it is discouraged to use array extents for such 
purpose. You may prefer bitfield widths, which would result in a better 
message:

```
struct static_assert_sem_failed
   { int unused : ((void *)0 == (sem_t *)0) ? 1 : -1; };

/*
lh_mouse@lhmouse-ideapad ~/Desktop $ gcc test.5.c  -Wall -Wextra 
-Wpedantic -Werror
test.5.c:4:9: error: bit-field ‘unused’ width not an integer constant 
expression [-Werror=pedantic]
    { int unused : ((void *)0 == (sem_t *)0) ? 1 : -1; };
*/
```


-- 
Best regards,
LH_Mouse

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Variably modified at file scope due to (void *)0 == (sem_t *)0?
  2018-10-04 12:28     ` Liu Hao
@ 2018-10-05  5:51       ` Sebastian Huber
  0 siblings, 0 replies; 5+ messages in thread
From: Sebastian Huber @ 2018-10-05  5:51 UTC (permalink / raw)
  To: Liu Hao, Jonathan Wakely; +Cc: gcc-help

On 04/10/2018 14:27, Liu Hao wrote:
>>>
>>>> The same expression in the
>>>> _Static_assert() doen't lead to a warning.
>>> It does with -pedantic, and that makes the reason for the warning 
>>> clearer:
>>>
>>> foo.c:5:26: warning: expression in static assertion is not an integer
>>> constant expression [-Wpedantic]
>>>   _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
>>
>> This looks bad, so basically a pointer constant doesn't exist in 
>> standard C?
>>
>
> As a difference from C++, C does not allow pointer operands in an 
> /integer constant expression/, despite the type of results of pointer 
> comparison, which is `int`.
>
> Because of VLAs, it is discouraged to use array extents for such 
> purpose. You may prefer bitfield widths, which would result in a 
> better message:
>
> ```
> struct static_assert_sem_failed
>   { int unused : ((void *)0 == (sem_t *)0) ? 1 : -1; };
>
> /*
> lh_mouse@lhmouse-ideapad ~/Desktop $ gcc test.5.c  -Wall -Wextra 
> -Wpedantic -Werror
> test.5.c:4:9: error: bit-field ‘unused’ width not an integer constant 
> expression [-Werror=pedantic]
>    { int unused : ((void *)0 == (sem_t *)0) ? 1 : -1; };
> */
> ``` 

Thanks for highlighting this C/C++ difference with respect to pointer 
operands. In C++ it looks better.

#ifdef __cplusplus
#define _Static_assert static_assert
#endif

typedef struct { int i; } sem_t;

struct static_assert_sem_failed { int unused : ((void *)0 == (sem_t *)0) 
? 1 : -1; };

_Static_assert((void *)0 == (sem_t *)0, "sem_failed");

void f(void)
{
   struct f_static_assert_sem_failed { int unused : ((void *)0 == (sem_t 
*)0) ? 1 : -1; };

   _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
}

gcc -S -x c++ -o - sa.c > /dev/null -Wall -Wextra -pedantic

No warnings or errors.

gcc -S -x c -o - sa.c > /dev/null -Wall -Wextra -pedantic
sa.c:7:39: warning: bit-field ‘unused’ width not an integer constant 
expression [-Wpedantic]
  struct static_assert_sem_failed { int unused : ((void *)0 == (sem_t 
*)0) ? 1 : -1; };
                                        ^~~~~~
sa.c:9:26: warning: expression in static assertion is not an integer 
constant expression [-Wpedantic]
  _Static_assert((void *)0 == (sem_t *)0, "sem_failed");
                 ~~~~~~~~~~^~~~~~~~~~~~~
sa.c: In function ‘f’:
sa.c:13:43: warning: bit-field ‘unused’ width not an integer constant 
expression [-Wpedantic]
    struct f_static_assert_sem_failed { int unused : ((void *)0 == 
(sem_t *)0) ? 1 : -1; };
                                            ^~~~~~
sa.c:15:28: warning: expression in static assertion is not an integer 
constant expression [-Wpedantic]
    _Static_assert((void *)0 == (sem_t *)0, "sem_failed");

Only a pedantic warning unlike to the variant with the array.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-10-05  5:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-04  8:51 Variably modified at file scope due to (void *)0 == (sem_t *)0? Sebastian Huber
2018-10-04  8:58 ` Jonathan Wakely
2018-10-04  9:11   ` Sebastian Huber
2018-10-04 12:28     ` Liu Hao
2018-10-05  5:51       ` Sebastian Huber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).