2

I am porting some C++ code to GCC, and apperantly it isn't happy with C++ style casting when sapces are involved, as in unsigned int(-1), long long(ShortVar) etc... It gives an error: expected primary-expression before 'long'.

Is there any way to make peace with GCC without going over each one of those and rewrite in c-style?

uj2
  • 1,391
  • 2
  • 15
  • 15

3 Answers3

5

You want static_cast<unsigned int>(-1) and kin. Those tend to be viewed as the more C++-style casts, and don't have the same problem.

For what it's worth, you'd have to do:

template <typename T>
struct identity
{
    typedef T type;
};

And then:

identity<unsigned int>::type(-1);

Or in C++0x:

template <typename T>
using id = T;

id<unsigned int>(-1);

GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • 1
    I believe they're function-style casts. They're not valid in C. – rlbond Jun 03 '10 at 04:57
  • @rlbond: I think you're right, I thought they said (unsigned int)(-1), which also shouldn't work. – GManNickG Jun 03 '10 at 04:59
  • @GMan: Thanks. The point was that there are no parenthesis around the type names, as opposed to C. I'm trying to save the trouble of going over all of them, not specifically avoiding/favoring any sort of cast. Thought there might be some switch/hack. – uj2 Jun 03 '10 at 05:04
  • @GMan, I found out why they weren't parsed by GCC :) – Kornel Kisielewicz Jun 03 '10 at 05:18
  • GMan, it is the first time I see the C++0x notation you provided. Can you please offer any link/documentation on this (I'm curious to read more on it). Thanks. – utnapistim Jun 03 '10 at 11:40
  • 2
    @GMan, i'm glad you are an identity activist too, now xD – Johannes Schaub - litb Jun 03 '10 at 17:01
  • @utnapistim: They are called `template aliases`, you can get some results in Google with that. It's in §14.5.7 in the C++0x draft (n3092.pdf). @Johannes: Haha, I couldn't help it any longer. – GManNickG Jun 03 '10 at 18:22
3

GCC is correctly crying -- unsigned int(-1) is a notation that is not conformant with the C++03 standard (5.4.2):

An explicit type conversion can be expressed using functional notation (5.2.3), a type conversion operator (dynamic_cast, static_cast, reinterpret_cast, const_cast), or the cast notation:

cast-expression:
   unary-expression
   ( type-id ) cast-expression

Ergo, you can either correct the cast with the parenthesis, follow the excellent suggestions proposed by GMan :) -- and I'd truly recommend the latter.

Edit: the functional notation requires a simple-type-specifier:

5.2.3 - A simple-type-specifier (7.1.5) followed by a parenthesized expression-list constructs a value of the specified type given the expression list.

Simple type specifiers do not include the composite ones (the ones with spaces).

Kornel Kisielewicz
  • 55,802
  • 15
  • 111
  • 149
  • 7.1.5.2/1 describes _nested-name-specifier(opt) type-name_ as a valid construction for _simple-type-specifier_, and later clearly identifies `unsigned char` as a valid _type-name_. – Lightness Races in Orbit Apr 21 '14 at 17:34
0

The probability is high that you type static_cast<unsigned int>(-1), but really want std::numeric_limits<unsigned int>::max() or, if not applicable, UINT_MAX.

The difference is primarily in that the latter two express what you want. Casting -1 to unsigned int is less expressive, if at all, therefore not the preferred solution.

In general, prefer to write expressive code. You'll thank yourself later, and your fellow programmers and the HR department will not frown upon you.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130