3 ms·
I think the issue is that programmers want a type "pointer to int", for example, but C doesn't directly provide that type. It has a type, int, with a modifier (
by rootbear 6y ago
I think the issue is that programmers want a type "pointer to int", for example, but C doesn't directly provide that type. It has a type, int, with a modifier (asterisk) that can be applied to a declarator to make it a pointer to that type.
One way to create a pointer type in C would be to declare it using typedef:
typedef int * int_p;
then one can write:
int_p p, q, r;
and declare three pointers to int with perfect clarity, whereas using the C++ style, we'd get:
int* p, *q, *r;
which is very confusing, or,
int* p;
int* q;
int* r;
which is very verbose. I honestly don't know how C++ programmers typically handle this situation.
I have seen some code that strikes a middle ground:
int * p;
which is a little more clear, but doesn't address the multiple declarator situation.
So why don't C++ programmers use typedef? I don't know, other than I understand Stroustrup doesn't like it (not without reason).
(Edited for formatting and minor clarity corrections.)
- implicit 6y agoMost modern C++ code that I've seen restricts code to declaring a single variable per statement. It's not really a big deal because things are also always introduced at the latest possible position. Each is also typically given an initializer. I'd consider it suspicious if I were to see C++ that declared 3 uninitialized pointers back to back like this. And then you get to the codebases where the authors have chosen to embrace auto and type inference... :)
- 0xffff2 6y agoI handle it by outlawing multiple declaration on a single line. It may be more verbose, but it's much easier to read IMO. This has been a somewhat common rule in my experience.
- kazinator 6y agoThis is not "C++ style"; it's just a poorly considered style perpetrated by coders who are not familiar with the grammar. The C++ syntax is the same as C in this regard: a declaration has specifiers, and then one or more declarators. The exception are function parameters, where you have (at most) one declarator. > why don't C++ programmers use typedef? C++ programmers do use typedef. For instance: typedef std::map<from_this_type, to_this_type> from_to_map; C++ programmers probably use typedef a bit less than they used to, because of features like auto. When a C++ class/struct is declared, its name is introduced into the scope as a type name. Therefore, this C idiom is not required in C++: typedef struct foo { int x } foo; that cuts down some typedefs. If you used a typedef for a C++ class that isn't just a "POD", you have issues, because the typedef name doesn't serve as an alias in all circumstances. typedef class x { x(); } y; y::y() // cannot write x constructor this way { }
- Y_Y 6y agoIt's worth noting that this nice C logic falls apart when you do something like f(int &a); to mean "by reference" instead of what it should be, which is "get the address of a, and that will be an int" which is , of course, nonsense.
- kazinator 6y agoI don't follow. The above is not C. It's a C++ extension over C declaration syntax in such a way that the & is part of the declarator just like * . // Inexcusable trompe l'oeil: int& a, b; // OK; int &a, &b; Here, the mistake may be harder to catch, because the expressions a and b are both of type int, either way. // Intent: b is an alias of a. // Reality: b is a new variable, holding copy of x. int& a = x, b = a; I think what you mean is that the "declaration follows use" principle falls apart for C++ references. That is necessarily true because no operator is required at all to use a C++ reference, whereas the explicit & type construction operator is required in the declarator syntax to denote it. However, it has little to do with the issue that & is part of the declarator and not of the type specifiers. Declaration follows use also falls apart for function pointers in C, because while int (* pf)(int) can be used as result = (* pf)(arg), it is usually just used as result = pf(arg). Declaration follows use also falls apart for the -> notation. A pointer ptr is always being used as ptr->memb, but declared as struct foo *ptr which looks nothing like it. And of course, arrays can be used via pointer syntax, and pointers via array syntax, also breaking declaration follows use. Declaration follows use is only a weak principle used to help newbies get over some hurdles in C declaration syntax.
- optymizer 6y ago"pointer to int" is a type, because 'pointer to' is not a type qualifier like 'const'. You can call it a modifier but you'll quickly start making exceptions for any type that has a modifier to explain away why it's actually a different type with a different size. For example, sizeof(x) takes a type. The type argument for sizeof(int) is different than sizeof(int* ) and the results are different. sizeof(int*[3]) is different as well. These are all different types where pointers change the type. It's not the same type with a pointer modifier, there is no such thing.
- UncleMeat 6y ago> I honestly don't know how C++ programmers typically handle this situation. The verbose one. A few extra lines rarely matters. I think the number of times this has come up in my code base is very very small, maybe a few dozen extra lines across hundreds of thousands.
- sacado2 6y agoA C++ function declaring several uninitialized pointers one after the other is very suspicious anyway. It looks like the programmer is trying to write old-school (pre C99) C code (declaring all variables at the top of the function) in C++. Typedeffing pointers, especially for the sole purpose of "being less verbose" when declaring uninitialized pointers, is a red flag too.