2

this line of code isn't compiling for me on GCC 4.2.2

m_Pout->m_R[i][j] = MIN(MAX(unsigned short(m_Pin->m_R[i][j]), 0), ((1 << 15) - 1));

error: expected primary-expression before ‘unsigned’

however if I add braces to (unsigned short) it works fine.

can you please explain what type of casting (allocation) is being done here?

why isn't the lexical parser/compiler is able to understand this c++ code in GCC?

Can you suggest a "better" way to write this code? supporting GCC 4.2.2 (no c++11, and cross platform)

Gilad
  • 6,437
  • 14
  • 61
  • 119
  • 1
    GCC 4.2 is a very old compiler (2008). Please upgrade it to a newer version. You could download a newer version ([GCC 5.1](https://gcc.gnu.org/gcc-5/) in july 2015) and compile it from its source code. – Basile Starynkevitch Jul 14 '15 at 12:57
  • @BasileStarynkevitch if it was up to me... ohhh if only... :( – Gilad Jul 14 '15 at 12:57
  • Why can't you compile GCC 5 from it source code? You don't need any root permissions for that (just in the GCC 5 build tree ..`../gcc-5.1/configure --prefix=$HOME/soft --program-suffix=-mine`...) then `make` then `make install`) – Basile Starynkevitch Jul 14 '15 at 13:01
  • @BasileStarynkevitch: The problem is that GCC assumes a glibc version and Linux ships with a glibc version. The two are not necessarily the same and this can cause major problems. On Windows, Microsoft has made it quite explicit that the different MSVCRT versions are not part of the OS, and since 7.0 they're even named differently so they can co-exist. – MSalters Jul 14 '15 at 13:13
  • 1
    If you compile GCC from its source code, it will fit to the glibc you have. – Basile Starynkevitch Jul 14 '15 at 13:18
  • @MSalters, GCC doesn't assume a glibc version, that's complete nonsense. It probes the C library during the configure step to see what features are present, and adjusts itself accordingly. – Jonathan Wakely Jul 14 '15 at 13:46
  • I'm curious... How can people have managers forbidding usage of a recent GCC compiler, and forcing them to use an obsolete one, like the comments above are implicitly suggesting? [Peter principle](https://en.wikipedia.org/wiki/Peter_Principle) ? – Basile Starynkevitch Jul 14 '15 at 14:20
  • Well sometimes it means a very long delay in an already working system. Which juat doesn't worth the trouble. – Gilad Jul 14 '15 at 15:08
  • @JonathanWakely: Which includes the assumption that it will be compiling for the host environment. If you compile on the same machine as where you run the executable, then yes there's only one glibc and the assumption is valid. But when I build an executable on my desktop so the field engineers can put it on servers in the field, it's a bloody annoying complication. – MSalters Jul 15 '15 at 07:35
  • @MSalters, no, it doesn't assume compiling for the host environment, because you configure against the target glibc. If you're configuring against the wrong environment then you're doing it wrong. If the OP already has a working compiler then they already have either a native or cross-glibc in place, and so could use the same one when building a new GCC. – Jonathan Wakely Jul 15 '15 at 07:51
  • @BasileStarynkevitch, upgrading the compiler might mean rebuilding and retesting large numbers of third-party libraries, including fixing anything that breaks (C++ code written for GCC 4.2 is very unlikely to compile cleanly with recent releases). It might be a lot of work to revalidate everything, so needs to be coordinated and planned not just done blithely. Of course the more often you do it the easier each upgrade is likely to be ... going from 4.2 to 5.1 is a big jump. – Jonathan Wakely Jul 15 '15 at 07:56
  • @JonathanWakely: And if you don't pass any special option, the default (aka assumption) in configuring GCC is the glibc locally installed. It's fixable, yes, but you must explicitly configure GCC to match the target environment. – MSalters Jul 15 '15 at 08:38

3 Answers3

4
  1. unsigned short(m_Pin->m_R[i][j]) is a declaration with initialisation of an anonymous temporary, and that cannot be part of an expression.

  2. (unsigned short)(m_Pin->m_R[i][j]) is a cast, and is an expression.

So (1) cannot be used as an argument for MAX, but (2) can be.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
3

I think Bathsheba's answer is at least misleading. short(m_Pin->m_R[i][j]) is a cast. Why is it that the extra unsigned messing things up? It's because unsigned short is not a simple-type-specifier. The cast syntax T(E) works only if T is a single token, and unsigned short is two tokens.

Other types which are spelled with more than one token are char* and int const, and therefore these are also not valid casts: char*(0) and int const(0).

With static_cast<>, the < > are balanced so the type can be named with a sequence of identifiers, even static_cast<int const*const>(0)

MSalters
  • 173,980
  • 10
  • 155
  • 350
2

You could use the §2 in Bathsheba's answer but it is more idiomatic to use static_cast in C++:

static_cast<unsigned short>(m_Pin->m_R[i][j])

BTW, your error is not related to GCC. You'll get the same if using Clang/LLVM or any (C++99 or C++11) standard conforming C++ compiler.


But independently of that, you should use a much newer version of GCC. In july 2015 the current version is GCC 5.1 and your GCC 4.2.2 version is from 2007, which is very ancient.

Using a more recent version of GCC is worthwhile because:

  • it enables you to stick to a more recent version of C++, e.g. C++11 (compile with -std=c++11 or -std=gnu++11)

  • recent GCC have improved their diagnostics. Compiling with -Wall -Wextra will help a lot.

  • recent GCC are optimizing better, and you'll get more performance from your code

  • recent GCC have a better and more standard conforming standard C++ library

  • recent GCC are better for debugging (with a recent GDB), and have sanitizer options (-fsanitize=address, -fsanitize=undefined, other -fsanitize=.... options) which help finding bugs

  • recent GCC are more standard conforming

  • recent GCC are customizable thru plugins, including MELT

  • older GCC 4.2 is no more supported by the FSF, and you'll need to pay big bucks the few companies supporting them.

You don't need any root access to compile from its source code a GCC 5 compiler (or cross-compiler). Read the installation procedures. You'll build a GCC tailored to your particular libc (and you might even use musl-libc if you wanted to ....), perhaps by compiling outside of the source tree after having configured with a command like

 ...your-path-to/gcc-5/configure --prefix=$HOME/soft/ --program-suffix=-mine

then make then make install then add $HOME/soft/bin/ to your PATH and use gcc-mine and g++-mine

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547