-1

While going through the C11 standard document, I found that it is acceptable to put variable declarator in parentheses.

If, in the declaration ‘‘T D1’’, D1 has the form identifier then the type specified for ident is T. If, in the declaration ‘‘T D1’’, D1 has the form (D) then ident has the type specified by the declaration ‘‘T D’’. Thus, a declarator in parentheses is identical to the unparenthesized declarator, but the binding of complicated declarators may be altered by parentheses.

So I tried. I am using Clang with MSVC as back-end.

#include <stdio.h>

int main() {
    int (a),(b),(c);
    int p, q, r;
    printf("Value of a, b, c is %d, %d, %d\n", a, b, c);
    printf("Value of p, q, r is %d, %d, %d\n", p, q, r);
    return 0;
}

It generated output like this.

PS D:\C> .\a.exe
Value of a, b, c is 0, 1, 1069425288
Value of p, q, r is 0, 0, 0

I really didn't understand what is happening here, when variable is declared in parentheses it is certainly holding different default values. Can anyone explain?

Tejas Sarade
  • 1,144
  • 12
  • 17
  • 5
    You have not initialised the *values* of the variables. The compiler should have given you this basic warning. Local variables don't have default values, you must explicity give them values. The parentheses make no difference. – Weather Vane Jun 23 '18 at 18:38
  • Yes, I didn't initialize the variables, so I expected it to have default value of 0 just like variables declared without parentheses. – Tejas Sarade Jun 23 '18 at 18:40
  • 2
    Nope, only `static` variables are initialised to `0`. – Weather Vane Jun 23 '18 at 18:41
  • As the text that your are citing states, there is no difference between variables that are declared with or without parenthesis. The difference in values that you see is just a coincidence, because you have an erroneous program. – Jens Gustedt Jun 23 '18 at 18:44
  • This [previous question](https://stackoverflow.com/questions/21152138/local-variable-initialized-to-zero-in-c) asked why the value is `0` when local variables are not initialised. It is because that value *happened* to be there. – Weather Vane Jun 23 '18 at 18:45
  • Random values are taken – Prajval M Jun 23 '18 at 18:45
  • The fact that you got zeroes for p, q and r was accidental--not part of the C language. Some compilers will provide deliberate "garbage" initialization when compiling in debug mode, so that most failure-to-initialize errors will be caught during development where it's easy to fix. – Mike Housky Jun 23 '18 at 18:46
  • Put the `p q r` line before the `a b c` line and see what happens. – user3386109 Jun 23 '18 at 18:46
  • 1
    The bottom line is, don't worry about parentheses around declarators. I'm sure there's a case where they will make a difference, but I can't think of one offhand. In 40+ years of C programming, I can't recall doing that even once in a real program. – Mike Housky Jun 23 '18 at 18:51
  • @MikeHousky You've never used a pointer to an array? `int (*ptr)[10]` is an example where *"the binding of complicated declarators may be altered by parentheses"*. Without the parentheses, it's an array of pointers: `int *ptr[10]`. – user3386109 Jun 23 '18 at 18:56
  • @user3386109 Terminology gap on my part, I guess. To me, the declarator in that example is `(*ptr)[10]` ... the whole thing. I guess that `*ptr` is probably a declarator within a declarator, and yes...I obviously have used that. – Mike Housky Jun 23 '18 at 19:01
  • I tested extensively and these values are indeed just coincidence. As pointed out by @WeatherVane parentheses doesn't make any difference here. – Tejas Sarade Jun 23 '18 at 20:12

1 Answers1

2

As Weather Vane already stated. All variables are just uninitilized. Compiling with -Wall flags states you this: gcc t.c -std=c11 -Wall

    t.c: In function ‘main’:
t.c:6:5: warning: ‘a’ is used uninitialized in this function [-Wuninitialized]
     printf("Value of a, b, c is %d, %d, %d\n", a, b, c);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.c:6:5: warning: ‘b’ is used uninitialized in this function [-Wuninitialized]
t.c:6:5: warning: ‘c’ is used uninitialized in this function [-Wuninitialized]
t.c:7:5: warning: ‘p’ is used uninitialized in this function [-Wuninitialized]
     printf("Value of p, q, r is %d, %d, %d\n", p, q, r);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.c:7:5: warning: ‘q’ is used uninitialized in this function [-Wuninitialized]
t.c:7:5: warning: ‘r’ is used uninitialized in this function [-Wuninitialized]

On my system I just get some other machine dependent varying output.

>>> ./a.out 
Value of a, b, c is 1024607536, 22001, 1134350448,
Value of p, q, r is 32766, 0, 0

I supposed it's similar with Clang.

Paul Würtz
  • 1,641
  • 3
  • 22
  • 35
  • A compiler *can* initialise local variables although it is not *required* and must not be relied on. It might do that to make debugging easier, or to prevent snooping. – Weather Vane Jun 23 '18 at 18:52
  • Yes, I do get this kind of output with gcc but with the Clang p, q, r are always 0. – Tejas Sarade Jun 23 '18 at 19:01
  • 1
    @TejasSarade So? You can rely on leaving your car's parking brake off if the terrain is flat, but try that in hill country. You are using the "false positive" argument to say there is no problem. There is no *guarantee* that things will fail if you do them wrong; if it works, it is because you "got away with it", but then, when you present your demo to 1000 people on a different computer ***then*** it will fail. – Weather Vane Jun 23 '18 at 19:07