5
int main()
{
        int i = 0;
        int *p = &i;
        int *q = &&i;
        return 0;
}

When compiling this using gcc on Linux, I am getting the error

addr.c: In function ‘main’:
addr.c:6:2: error: label ‘i’ used but not defined

Why is the compiler treating int i as label and not integer? When do we use && operator?

EDIT: Okay, I can somewhat understand the answers, but can you explain the below macro definition from "arch/arm/include/asm/processor.h". It doesn't says anything about label, but the comment says, it can return the "program counter"

/*
 * Default implementation of macro that returns current
 * instruction pointer ("program counter").
 */
#define current_text_addr() ({ __label__ _l; _l: &&_l;})
manav m-n
  • 11,136
  • 23
  • 74
  • 97
  • What should `&&i` do? It's not like the pointer to `i` needs to be stored somewhere. You could try `int *q = &p`. – John Dvorak Dec 17 '12 at 13:31
  • 1
    `&&i` makes about as much sense as `&5`. You can't get the address of an rvalue. – Pubby Dec 17 '12 at 13:34
  • @Pubby remember maximal munch! `&&i` will never get parsed as `&(&i)`. (also, consider the dreaded overloaded unary `operator&` :P) – R. Martinho Fernandes Dec 17 '12 at 13:35
  • @R.MartinhoFernandes I know, but OP clearly intends `& &`. – Pubby Dec 17 '12 at 13:36
  • I thought that too, but `q` is not an `int**` so I am not really sure. – R. Martinho Fernandes Dec 17 '12 at 13:37
  • 1
    what do you want to achieve? The error message says it all, you are trying to interpret `i` as a label, `&&` aplies to labels. So what is your question? – Jens Gustedt Dec 17 '12 at 13:40
  • Did you want C or C++? You tagged both. – Mike Dec 17 '12 at 13:41
  • @JensGustedt The question is quite clear. I never saw this, and as it turns out, it is a gcc extension. – BЈовић Dec 17 '12 at 14:06
  • 2
    The `current_text_addr` macro defines the label `_l` and then evaluates to the address of that label. Since the label is where the macro is, its address is where the program is currently executing, also known as the program counter. The macro uses compiler extensions; it is not standard C and will not be portable. `__label__` declares a label that is local to the current block (the statements between `{` and `}`). This prevents `_l` from interfering with other variables named `_l`. Then `_l:` defines the label. Then `&&_l;` is an expression statement that is the address of the label. – Eric Postpischil Dec 17 '12 at 15:19
  • The `({` and `})` are a compiler extension that allow multiple statements inside an expression. Its value is the value of the last statement inside the parentheses. – Eric Postpischil Dec 17 '12 at 15:20

3 Answers3

15

What && operator? There is no unary && operator in C++. GCC has an extension that allows computed goto statements, and that extension uses && to get the address of a label.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
10

Here && is the GNU C label address operator.

http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html

int *q = &&i;

i must be a label. You have no label i in your program.

Example of a label:

int main(void)
{
    i:
    (void) 0;

     int i = 0;
     int *p = &i;
     int *q = &&i;
     return 0;
}

I added the (void) 0; statement as labels in C can only put before statements and not before declarations.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • 1
    This answer is not useful. Why should `i` be a label? The example does not clarify that a bit. – John Dvorak Dec 17 '12 at 13:33
  • 4
    This answer is correct. `&&` is used by `gcc` to get the address of a label. Why the downvote? – alk Dec 17 '12 at 13:35
  • @alk it does (did) not explain what `&&` does or that it's `gcc` specific. – John Dvorak Dec 17 '12 at 13:36
  • 1
    @JanDvorak The question is tagged with gcc. – Pubby Dec 17 '12 at 13:38
  • @JanDvorak Just reload ... – alk Dec 17 '12 at 13:38
  • It is worth mentioning that labels and variables exist in different scopes (name spaces) in standard C, and that is why this code would compile, even though there is a label i: and a variable int i with the same names. – Lundin Dec 17 '12 at 14:02
  • "*... added the (void) 0; ...*": wouldn't a single `;` do also? Also if I remember correctly labels do not need to be declared in the source **before** their address is taken but simply somewhere. – alk Dec 17 '12 at 14:16
  • @alk yes `;` would probably be ok as it is the null statement. Same for the `{}` statement. – ouah Dec 17 '12 at 15:49
4

& is used two ways, first, you can get the address of a variable:

int *p = &i; // that's fine, p points to i's address

Second it's used to do a "bit-wise" and:

int i = 1;     // 01
int j = 3;     // 11
int k = i & j; // 01

&& is a logical operator, not an "address of address of" operator, it's use is in checking two conditions together and asserting that both are true.

if (something && something_else)

EDIT: I just noticed you taged this as C and C++... if this is a C question, see above. If this is a C++ question there's another note on &&:

C++ Double Address Operator? (&&)


EDIT 2: There's another use of the && as a label value operator to take the address of the label.

This is what the error message is about since the compiler is assuming that's what you wanted to do:

The label value operator && returns the address of its operand, which must be a label defined in the current function or a containing function. The value is a constant of type void* and should be used only in a computed goto statement. The language feature is an extension to C and C++, implemented to facilitate porting programs developed with GNU C.

int main()
{
   void * ptr1;
   label1: ...
   ptr1 = &&label1;

   ...

   if (...) {
      goto *ptr1;
   }
   ...
}
Community
  • 1
  • 1
Mike
  • 47,263
  • 29
  • 113
  • 177