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.