7

What's the difference between float* varname and float *varname in classic C?

nobody
  • 19,814
  • 17
  • 56
  • 77
acheo
  • 3,106
  • 2
  • 32
  • 57
  • There is no difference, the compiler is happy either way. 'C' programmers tend to favor the space after the type name, causes less confusion when you declare more than one variable. This *has* to be dupe. – Hans Passant Jan 24 '10 at 23:03
  • 1
    You've opened up a religious can of worms. :) I'm surprised that most of the answers so far are mild-mannered. – Dan Olson Jan 24 '10 at 23:10
  • 1
    Wasn't this asked yesterday but with `int` being the type instead? And yesterday's question was a duplicate of a duplicate of a duplicate? – James Morris Jan 24 '10 at 23:13
  • show me the dupe please i didn't find it – acheo Jan 24 '10 at 23:24
  • 1
    @James and @Peanut: It's true that it has been asked before. But it is very difficult to search for them, unless you happen to guess the variable names that were used in the examples. However here's one from last week: http://stackoverflow.com/questions/2065232/. You can find the other duplicates by scraping recursively from that post! – Daniel Vassallo Jan 24 '10 at 23:32
  • @Daniel thanks I didn't try searching on other types, just checked the context search list that came up and didn't see anything – acheo Jan 25 '10 at 10:08

6 Answers6

22

Formatting. That's it. They mean the same thing.

Where you put the space (or if you even have one, really) is a matter of preference. Some prefer the * next to the varname so that you don't get confused by something like:

float* a, b;

(here, only a is a pointer, b is not)

Others argue that they never declare multiple variables at once, so they prefer the * next to float, since it's part of the type.

Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • 2
    One wonders how those who put the `*` next to `float` because "it's part of the type" ever manage to declare arrays. – caf Jan 24 '10 at 23:22
  • 1
    You still can't put the `[N]` next to the rest of the type, though. – caf Jan 25 '10 at 00:19
  • 1
    @caf: That's why I find the whole "it describes the type" argument to be specious, because it's inconsistent with *every other type*; every time I see something like `int* a[10];` or `double* foo();` it just screams confused thinking to me. – John Bode Jan 25 '10 at 01:57
  • @caf: Sure you can. If you say `template struct identity { typedef T type; };` then you can say `identity::type numbers;` which puts the `[N]` part right next to the type. – fredoverflow Feb 20 '11 at 22:41
  • @FredOverflow: That's an egregious syntax error in C, and this question is specifically about "classic C". – caf Feb 20 '11 at 22:53
  • @caf: Whoops, sorry, I was still in C++ mode :) – fredoverflow Feb 20 '11 at 23:02
8

There is no difference. The whitespace is completely ignored.

However note that the following can be misleading:

float* var1, var2;

Casual examination of the above would lead you to think that both var1 and var2 are pointers to a float. However you'd be wrong, because this declares var1 as a pointer to a float, but var2 would be a regular float.

Daniel Vassallo
  • 337,827
  • 72
  • 505
  • 443
  • It's an interesting thing that C considers the * to be associated more with the variable name than with the pointer-to type. Kind of makes you wish for the old Pascal colon as a disambiguation - separate the shared type from the names-with-modifiers list. –  Jan 24 '10 at 23:19
  • 1
    @Steve314 But think about what happens when you have `typedef int *foo_t;`, then `foo_t a, b, c;`. At that point C "considers" the `*` to be associated with the type. (Although I would argue that the C language doesn't really "consider" anything...) – asveikau Jan 24 '10 at 23:33
4

The latter is more explicit in that it shows that you are creating a variable which is a pointer to a float, instead of creating a variable that is a float pointer. This becomes important in constructs such as:

float *foo, bar;

foo is a pointer to a float, but bar is just a float.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
1

Mostly, it is a matter of coding style. However, most C programmers prefer to use the second option: float *var; as it is closer to how the language syntax binds the * asterisk: the * is bound to the declarator, not the specifier of type.

In other words, C programmers translate float *var as *var is of type of float. but not var is of type of float*.

There is more elaborate explanation in Wikipedia article C variable types and declarations

Also, you may find the question C Pointer Syntax: Style poll interesing.

Community
  • 1
  • 1
mloskot
  • 37,086
  • 11
  • 109
  • 136
0

As others said, it makes no difference - matter of style. Note that in C++ it's customary to write:

type* var;

Because the pointer is part of the type - at least this true for custom types. But by extension for built-in types too. So it makes some sense in C to do the same to be consistent. Personally I find it more intuitive to have pointer part of the type.

zaharpopov
  • 16,882
  • 23
  • 75
  • 93
0

There is effectively no difference; the declaration is parsed as though it were written float (*varname);.

In both C and C++, declarations are centered around expressions, not objects; basically, the form of the declaration should match the form of the expression in executable code (IOW, declaration mimics use). For example, if you have a pointer to an integer named p and you want to access that integer value that p points to, you dereference the pointer like so:

x = *p;

The type of the expression *p is int; thus, the declaration should look like

int *p;

Similarly, if you have an array of int named arr and you want to access the integer value at a specific element i, you would write

x = a[i];

The type of the expression a[i] is int; thus, the declaration should look like

int a[N];

In the examples above, *p and a[N] are called declarators; declarators introduce the name of the object being declared along with additional type information not provided in the type specifier. The int-ness of both p and a are provided by the type specifier int, but the pointer-ness of p and the array-ness of a are provided by their respective declarators.

This is an important point, and something that needs to be stressed; the * of both int *p; and int* p; is bound to the declarator, not the type specifier, regardless of whitespace. The fact that you can write it either way is an accident of C (and C++) syntax, and as a result there's a school of thought that pointer variables should be declared as T* p; as opposed to T *p;, since the type of p is "pointer to T". My problem is that reasoning only works for simple pointer types; we cannot treat array or function types the same way. For example, we cannot write int[N] arr;, even though the type of arr is "N-element array of int". It really falls down when we get into declaring pointers to arrays, or pointers to functions, or combinations of such. For example:

int *(*(*(*farr)())[N])();

The type of farr is "pointer to a function returning a pointer to an N-element array of pointers to functions returning pointers to int". Everything other than the "int" is part of the declarator; writing int* (*(*(*farr)())[N])(); or even int*(*(*(* farr)())[N])(); would just be ... silly.

I believe that insisting on writing T* p; for pointer declarations results in more confusion, not less. Much as Stroustrup and legions of C++ programmers would like to pretend otherwise, declarations in C and C++ are centered around expressions, not objects.

Since I'm part of a larger team writing C++ code, I follow the agreed-upon coding guidelines which include declaring pointer and references as T* p; and T& r;, but it makes me grind my teeth every time I have to do it.

John Bode
  • 119,563
  • 19
  • 122
  • 198