This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Parse Error on explicit type conversion
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: Parse Error on explicit type conversion
- From: Chad dot Farmer at bull dot com
- Date: Fri, 15 Oct 1999 12:10:43 -0700
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.