Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does <signal.h> prevent the use of "si_" as prefix for the name of some variables?

Tags:

c++

c

linux

I have been debugging a strange compilation error that I was getting inside my code, and I ended up finding out that I cannot use the prefix si_ for some variable names (of any type) if <signal.h> is included.

Here is a very simple source code example that reproduces the issue:

#include <signal.h>

int main(void)
{
    int si_value = 0;

    return 0;
}

If I try to compile this with the GNU C Compiler gcc, I get the following error:

> gcc example.c
In file included from /usr/include/signal.h:57:0,
                 from example.c:2:
example.c: In function ‘main’:
example.c:6:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
     int si_value = 0;
         ^
example.c:6:9: error: expected expression before ‘.’ token

Nonetheless, if I use another name such as si_value2, the error doesn't show up. As a reference, I'm using GCC v7.3.0 on Ubuntu Mate 18.04.1 LTS. The same problem is observed with g++.

I suppose that this behaviour is due to some macro definition inside the <signal.h> header, but after going through it briefly, I couldn't seem to find anything really related.

I honestly can fix it by just using another name. However, my concern is: how could I elegantly avoid this type of issue in the future?


Update: As @F.X. has suggested, using gcc -E example.c shows that the variable name is expanded (hence, the error):

...
    int 
# 6 "example.c" 3 4
       _sifields._rt.si_sigval 
# 6 "example.c"
                = 0;
...
like image 284
SRG Avatar asked Nov 07 '18 20:11

SRG


2 Answers

<signal.h> doesn't actually prevent using si_ as a prefix on your variables. However, the POSIX specification states that this prefix is reserved, in order to allow the header and the library functions that it declares to use these names, without having to worry that they'll conflict with your own variables.

So what's happening here is that si_value is defined in some way in the header file, perhaps as a macro or typedef, and your attempt to use the same name conflicts with this. If you used si_vy1ghad563nvy43wd it probably would work, but theoretically the header could use that name (thinking that it would be unlikely to conflict with anything an application programmer would use).

C doesn't have real namespaces, so naming conventions like this are used as a simple substitute.

like image 179
Barmar Avatar answered Nov 17 '22 08:11

Barmar


how could I elegantly avoid this type of issues in the future?

You check some documentation for the headers you are using and avoid the names that are documented as reserved.

like image 32
Baum mit Augen Avatar answered Nov 17 '22 07:11

Baum mit Augen