This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Parse Error on explicit type conversion


A function-style explicit type conversion to a 64-bit integer gets an error
"parse error before `long'".
g++ accepts int(x) or unsigned(x), but not unsigned int(x) or unsigned long long
int(x).  It appears that with g++, only a single word can be used for
function-style explicit type conversion.  For example, "int(x)", "unsigned(x)"
and "typedefname(x)" all work, but "unsigned int(x)" does not.

I'm not certain that this is an error, but Microsoft's VC++ 5.0 does accept
multi-word explicit type conversion like "unsigned __int64(x)".  (Note that in
addition to VC++ using "__int64" for "long long int", a printf format string
uses "I64", rather than "ll" to specify 64-bits.)

A cast-style conversion "(unsigned long long int) x" works for both g++ and
VC++, "(unsigned __int64) x".

I encountered this incompatibility(?) when porting code from VC++.  Since I've
identified several ways to avoid the problem, I don't need a patch.  I thought
you might be interested, particularly if you are tracking differences between
g++ and other compilers.  Note that without the type conversion, a and a1 do not
get the desired value.  (Ignore values of variables not assigned, c, e, c1 and
e1).

I've included an example program below.  I commented out the problem lines so
that I could run the program.  To see the compile errors, remove the "//" from
assignments to c, e, c1 and e1.

Chad Farmer
(602)862-4102

$ cat cast.cpp
/* cast.cpp  Test conversion to 64-bit integer
/*
/**/
#include <stdio.h>

#define uint64 unsigned long long int
typedef unsigned long long int ui64;

void main() {

    uint64 a;
    uint64 b;
    uint64 c;
    uint64 d;
    uint64 e;
    uint64 f;
    unsigned short int x = 0xff;
    unsigned long int g;

    g = x << 24;
    printf("g=%08lx.\n",g);
    g = int(x) << 24;
    printf("g=%08lx.\n",g);
    g = unsigned(x) << 24;
    printf("g=%08lx.\n",g);

    a = x << 24;
    b = ui64(x) << 24;
    //c = uint64(x) << 24;
    d = (unsigned long long int) x << 24;
    //e =  unsigned long long int(x) << 24;
    f = (ui64) x << 24;

    printf("a=%016llx, b=%016llx, c=%016llx, d=%016llx, e=%016llx,
f=%016llx.\n",
        a, b, c, d, e, f );

    uint64 a1;
    uint64 b1;
    uint64 c1;
    uint64 d1;
    uint64 e1;
    uint64 f1;

    a1 = x << 32;
    b1 = ui64(x) << 32;
    //c1 = uint64(x) << 32;
    d1 = (unsigned long long int) x << 32;
    //e1 =  unsigned long long int(x) << 32;
    f1 = (ui64) x << 32;

    printf("a1=%016llx, b1=%016llx, c1=%016llx, d1=%016llx, e1=%016llx,
f1=%016llx.\n",
        a1, b1, c1, d1, e1, f1 );

}/* end main */

$# Using RedHat Linux
$ uname -a
Linux fellows 2.2.10 #4 SMP Mon Jul 19 14:28:42 MST 1999 i686 unknown$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
]$ g++ cast.cpp -o cast
cast.cpp: In function `int main(...)':
cast.cpp:44: warning: left shift count >= width of type
$ ./cast
g=ff000000.
g=ff000000.
g=ff000000.
a=ffffffffff000000, b=00000000ff000000, c=00000001bffffda4, d=00000000ff000000,
e=40009e70bffffd58, f=00000000ff000000.
a1=00000000000000ff, b1=000000ff00000000, c1=0000000740010187,
d1=000000ff00000000, e1=400136584001faec, f1=000000ff00000000.
$

Note: the output from this program (including assignments to c, e, c1, e1) using
VC++ and Windows is:
g=ff000000.
g=ff000000.
g=ff000000.
a=ffffffffff000000, b=00000000ff000000, c=00000000ff000000, d=00000000ff000000,
e=00000000ff000000, f=00000000ff000000.
a1=00000000000000ff, b1=000000ff00000000, c1=000000ff00000000,
d1=000000ff00000000, e1=000000ff00000000, f1=000000ff00000000.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]