40

Two question regarding decltype and typeof:

  • Is there any difference between the decltype and typeof operators?
  • Does typeof become obsolete in C++11?
David G
  • 94,763
  • 41
  • 167
  • 253
MBZ
  • 26,084
  • 47
  • 114
  • 191
  • 18
    Keep in mind `typeof` was never standard. – GManNickG Jan 02 '13 at 23:19
  • 7
    One exists, the other doesn't :-) Also note that `decltype` has well-defined and interesting semantics that allow you to say something like `decltype(x)&&` in a very general setting. – Kerrek SB Jan 02 '13 at 23:26

5 Answers5

34

There is no typeof operator in c++. While it is true that such a functionality has been offered by most compilers for quite some time, it has always been a compiler specific language extension. Therefore comparing the behaviour of the two in general doesn't make sense, since the behaviour of typeof (if it even exists) is extremely platform dependent.

Since we now have a standard way of getting the type of a variable/expression, there is really no reason to rely on non portable extensions, so I would say it's pretty much obsolete.

Another thing to consider is that if the behaviour is of typeof isn't compatible with decltype for a given compiler it is possible that the typeof extension won't get much development to encompass new language features in the future (meaning it might simply not work with e.g. lambdas). I don't know whether or not that is currently the case, but it is a distinct possibility.

Grizzly
  • 19,595
  • 4
  • 60
  • 78
  • 2
    It's not quite obsolete due to `decltype` alone, as the reference dropping semantics of `typeof` (in gcc, EDG, Metroworks) was useful for declaring local variables of that type. However, when combined with `auto` too, it is now pretty unnecessary. It's sad that we couldn't have used the ideally named `typeof` (rhymes with `alignof`, `sizeof`) due to existing implementation differences. – Dwayne Robinson Nov 02 '14 at 08:50
23

The difference between the two is that decltype always preserves references as part of the information, whereas typeof may not. So...

int a = 1;
int& ra = a;
typeof(a) b = 1;     // int
typeof(ra) b2 = 1;   // int
decltype(a) b3;      // int
decltype(ra) b4 = a; // reference to int

The name typeof was the preferred choice (consistent with sizeof and alignof, and the name already used in extensions), but as you can see in the proposal N1478, concern around compatibility with existing implementations dropping references led them to giving it a distinct name:

"We use the operator name typeof when referring to the mechanism for querying a type of an expression in general. The decltype operator refers to the proposed variant of typeof. ... Some compiler vendors (EDG, Metrowerks, GCC) provide a typeof operator as an extension with reference-dropping semantics. As described in Section 4, this appears to be ideal for expressing the type of variables. On the other hand, the reference-dropping semantics fails to provide a mechanism for exactly expressing the return types of generic functions ... In this proposal, the semantics of the operator that provides information of the type of expressions reflects the declared type. Therefore, we propose the operator to be named decltype."

J. Jarvi, B. Stroustrup, D. Gregor, J. Siek: Decltype and auto. N1478/03-0061.

So it's incorrect to say that decltype completely obviated typeof (if you want reference dropping semantics, then the typeof extension in those compilers still has use), but rather, typeof was largely obviated by it plus auto, which does drop references and replaces uses where typeof was used for variable inference.

  • update 2023-01-03 C23 will evidently officially get typeof in N2927.
  • update 2023-08-28 For C++26, there is p2958r0.
Dwayne Robinson
  • 2,034
  • 1
  • 24
  • 39
9

For legacy code, I have been using successfully the following:

#include <type_traits>
#define typeof(x) std::remove_reference<decltype((x))>::type
user377178
  • 2,363
  • 3
  • 16
  • 11
  • Why the extra `()`s? The difference between `decltype(x)` and `decltype((x))` is usually only extra `&`s, which you proceed to remove anyhow? Or am I missing something? – Yakk - Adam Nevraumont Jun 06 '16 at 15:30
  • The extra parentheses are meant to be defence against unshielded commas in parameter x, however only would be a threat in case decltype was a macro. The need for them is arguable – user377178 Jun 07 '16 at 21:53
  • 3
    you'll also need `...` and `__VA_ARGS__` or `bob` as an argument will not be parsed right by the c preprocessor. – Yakk - Adam Nevraumont Jun 07 '16 at 22:13
  • good point, otherwise one need using extra parentheses around argument to typeof, However, if decltype macro followed the ... scheme the extra parentheses within decltype((x)) would not be needed. – user377178 Jun 08 '16 at 12:34
1

typeof has not been standardized, although it was implemented by several compiler vendors, e.g., GCC. It became obsolete with decltype.

A good explanation for the shortcomings of typeof can be found in this related answer.

Community
  • 1
  • 1
Philipp Claßen
  • 41,306
  • 31
  • 146
  • 239
1

Well, typeof is a non-standard GNU C extension that you can use in GNU C++ because GCC allows you to use features from other languages in another (not always though), so they really shouldn't be compared.

Of course other non-standard extensions may exist for other compilers, but GCC is definitely the most widely documented implementation.

To answer the question: it can't be obsolete if it was never a feature.

If you want to compare the merits of either method in C++ then there is semantically no difference unless you're dealing with references. You should use decltype because it is portable and standards conforming.

RamblingMad
  • 5,332
  • 2
  • 24
  • 48