Jeremy
Jeremy

Reputation: 5321

Why does GCC define unary operator '&&' instead of just using '&'?

As discussed in this question, GCC defines nonstandard unary operator && to take the address of a label.

Why does it define a new operator, instead of using the existing semantics of the & operator, and/or the semantics of functions (where foo and &foo both yield the address of the function foo())?

Upvotes: 24

Views: 4006

Answers (2)

haccks
haccks

Reputation: 106102

GCC added this extension to be used in initializing a static array that will serve as a jump table:

static void *array[] = { &&foo, &&bar, &&hack };  

Where foo, bar and hack are labels. Then a label can be selected with indexing, like this:

goto *array[i];   

Standard says that

C11: 6.2.1 Scopes of identifiers (p1):

An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter.

Further it says in section 6.2.3:

If more than one declaration of a particular identifier is visible at any point in a translation unit, the syntactic context disambiguates uses that refer to different entities. Thus, there are separate name spaces for various categories of identifiers, as follows:

label names (disambiguated by the syntax of the label declaration and use);

— the tags of structures, unions, and enumerations (disambiguated by following any32) of the keywords struct, union, or enum);

— the members of structures or unions; each structure or union has a separate name space for its members (disambiguated by the type of the expression used to access the member via the . or -> operator);

— all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).

This means that an object and a label can be denoted by same identifier. At this point, to let the compiler know that the address of foo is the address of a label, not the address of an object foo (if exists), GCC defined && operator for address of label.

Upvotes: 9

Sebastian Redl
Sebastian Redl

Reputation: 72054

Label names do not interfere with other identifiers, because they are only used in gotos. A variable and a label can have the same name, and in standard C and C++ it's always clear from the context what is meant. So this is perfectly valid:

name:
  int name;
  name = 4; // refers to the variable
  goto name; // refers to the label

The distinction between & and && is thus needed so the compiler knows what kind of name to expect:

  &name; // refers to the variable
  &&name; // refers to the label

Upvotes: 39

Related Questions