Compile errors?

B

BartC

I have this code:

#include <stdio.h>
#include <stdint.h>

int main(void) {
int *a;
int32_t x;
unsigned char* s;

s="ABC";

a=&x;
}

With one compiler (Digital Mars), I get an error on s="ABC" (need explicit
cast from char* to unsigned char*), and on a=&x (need explicit cast from
long* to int*, even though both long and int are the same size).

Is the compiler being over-the-top, or is it justified in reporting these as
errors and not warnings?

(I'm not going to go sticking (unsigned char*) in front of every single
string literal in my programs, so I doubt I'm going to be using that
compiler much.)
 
E

Eric Sosman

I have this code:

#include <stdio.h>
#include <stdint.h>

int main(void) {
int *a;
int32_t x;
unsigned char* s;

s="ABC";

a=&x;
}

With one compiler (Digital Mars), I get an error on s="ABC" (need
explicit cast from char* to unsigned char*), and on a=&x (need explicit
cast from long* to int*, even though both long and int are the same size).

Is the compiler being over-the-top, or is it justified in reporting
these as errors and not warnings?

(I'm not going to go sticking (unsigned char*) in front of every single
string literal in my programs, so I doubt I'm going to be using that
compiler much.)

The compiler is right about the signed/unsigned char* mismatch.
`char' and `unsigned char' are distinct types (even on implementations
where their ranges are identical), so `char*' and `unsigned char*' are
distinct types. If it is your habit to initialize `unsigned char*'
variables with string literals, you have formed a bad habit.

It is implementation-defined whether the compiler is right to
complain about int/int32_t. On an implementation where int32_t is
a typedef for int there is no problem. On an implementation where
int32_t is some other type (you mentioned long), there is a mismatch
and the compiler must object.
 
J

James Kuyper

I have this code:

#include <stdio.h>
#include <stdint.h>

int main(void) {
int *a;
int32_t x;
unsigned char* s;

s="ABC";

a=&x;
}

With one compiler (Digital Mars), I get an error on s="ABC" (need explicit
cast from char* to unsigned char*), and on a=&x (need explicit cast from
long* to int*, even though both long and int are the same size).

Is the compiler being over-the-top, or is it justified in reporting these as
errors and not warnings?

The mismatch between x and a is clearly an error, the fact that long and
int are the same size is irrelevant. It's a bad idea to rely upon it
working even if int32_t was a typedef for int on your system. If you
want two things to have compatible types, you should declare them so
they are explicitly compatible.
(I'm not going to go sticking (unsigned char*) in front of every single
string literal in my programs, so I doubt I'm going to be using that
compiler much.)

You can prefix the string literal with a 'u' or a 'U' to make it
unsigned. This is a new feature in C2011, I've no idea whether Digital
Mars supports it.
 
B

Ben Bacarisse

James Kuyper said:
You can prefix the string literal with a 'u' or a 'U' to make it
unsigned. This is a new feature in C2011, I've no idea whether Digital
Mars supports it.

I don't think the u (or U) prefix does what you think. It makes the
string literal wide and:

"For wide string literals prefixed by the letter u or U, the array
elements have type char16_t or char32_t,..."
 
J

James Kuyper

I don't think the u (or U) prefix does what you think. It makes the
string literal wide and:

"For wide string literals prefixed by the letter u or U, the array
elements have type char16_t or char32_t,..."

I remembered the new prefixes, opened a copy of the standard for a
moment to confirm that they did exist, and didn't bother reviewing what
it actually said about them. Sorry!
 
J

Jorgen Grahn

I have this code:

#include <stdio.h>
#include <stdint.h>

int main(void) {
int *a;
int32_t x;
unsigned char* s;

s="ABC";

a=&x;
}

With one compiler (Digital Mars), I get an error on s="ABC" (need explicit
cast from char* to unsigned char*),

I get that with the popular gcc too, if I enable any warnings at all.
and on a=&x (need explicit cast from
long* to int*, even though both long and int are the same size).

I don't get that at all, probably because int and int32_t are synonyms
on my targets (gcc on amd64 and ppc).
(I'm not going to go sticking (unsigned char*) in front of every single
string literal in my programs, so I doubt I'm going to be using that
compiler much.)

/Jorgen
 
B

BartC

Jorgen Grahn said:
I don't get that at all, probably because int and int32_t are synonyms
on my targets (gcc on amd64 and ppc).

(Is that a gcc version producing 64-bit code for amd64? If, do you have a
link to where I can download a working binary distribution? The only such
version I've found was unofficial and didn't work.)
 
I

Ian Collins

BartC said:
(Is that a gcc version producing 64-bit code for amd64? If, do you have a
link to where I can download a working binary distribution? The only such
version I've found was unofficial and didn't work.)

Eh? gcc has supported 64bit builds on x64 platforms for many years now.
How else would the BSD and Linux kernels get built?
 
B

BartC

Ian Collins said:
Eh? gcc has supported 64bit builds on x64 platforms for many years now.
How else would the BSD and Linux kernels get built?

I'm not disputing /a/ version of gcc generating 64-bit code exists. I was
asking, if Jorgen had such a compiler, if he knew where I could download a
copy. However I forgot that he was probably talking a non-Windows version.

A version for Windows seems extraordinarily difficult to obtain (nothing
connected with gcc is ever simple!). Some downloads look like they might be
it but turn not to be an actual compiler. Or they don't work.

However, I've just tried something called TDM-GCC and it seems promising
(although it clashed with my existing mingw at first with strange errors). A
program printing sizeof(int*) gives 4 when I use gcc -m32, and 8 when using
gcc -m64! I will do some more tests.

(I have a couple of other Windows compilers with 64-bit output, but the
optimisers aren't good enough so the 64-bit code will probably be slower
than the 32-bit code of gcc.)
 
J

James Harris

....
I'm not disputing /a/ version of gcc generating 64-bit code exists. I was
asking, if Jorgen had such a compiler, if he knew where I could download a
copy. However I forgot that he was probably talking a non-Windows version.

A version for Windows seems extraordinarily difficult to obtain (nothing
connected with gcc is ever simple!).

On the contrary, nothing to do with software development *on Windows* is
ever simple.

James
 
J

Jorgen Grahn

I'm not disputing /a/ version of gcc generating 64-bit code exists. I was
asking, if Jorgen had such a compiler, if he knew where I could download a
copy. However I forgot that he was probably talking a non-Windows version.

True, I was. I'm using Debian Linux, on various hardware.
Never really tried to do any programming on Windows.

/Jorgen
 
K

Keith Thompson

Eric Sosman said:
The compiler is right about the signed/unsigned char* mismatch.
`char' and `unsigned char' are distinct types (even on implementations
where their ranges are identical), so `char*' and `unsigned char*' are
distinct types. If it is your habit to initialize `unsigned char*'
variables with string literals, you have formed a bad habit.

Furthermore, assignment, initialization, and argument passing include an
implicit conversion between char and unsigned char (as between any two
arithmetic types), so the fact that they're distinct types very often
doesn't cause any visible errors. But there is no such implicit
conversion between the pointer types char* an unsigned char*.
Converting a plain char to unsigned char, or vice versa, converts the
*value*. Converting a pointer to an incompatible pointer type enables
reinterpreting an object of the target type as if it were an object of a
different type, which is why such conversions require an explicit cast
(except for the special case of void*).

Usually plain char should be used for actual character data, and
unsigned char should be used for binary data. String literals are of
type array of (plain) char. If you're using string literals for
unsigned char data, you might want to rethink your design.

On the other hand, it occurs to me that it would be nice if
the language had a syntax for string literals of type array
of unsigned char, perhaps U"ABC", which would be equivalent to
(unsigned char[]){'A', 'B', 'C', '\0'}.
It is implementation-defined whether the compiler is right to
complain about int/int32_t. On an implementation where int32_t is
a typedef for int there is no problem. On an implementation where
int32_t is some other type (you mentioned long), there is a mismatch
and the compiler must object.

And it must do so even if int and long happen to have the same
representation. (The objection may be either a fatal error or a
warning.)
 
G

Geoff

However, I've just tried something called TDM-GCC and it seems promising
(although it clashed with my existing mingw at first with strange errors). A
program printing sizeof(int*) gives 4 when I use gcc -m32, and 8 when using
gcc -m64! I will do some more tests.

Why would you be surprised by this?
 
L

Les Cargill

James said:
...


On the contrary, nothing to do with software development *on Windows* is
ever simple.

James

I use the Ningw toolchain on Windows ( just the compiler ). It's almost
like using a real computer. :)

If I need a GUI, I launch a console mode program as a pipe in Tcl. I'm
sure Python is just as a capable.
 
B

BartC

Geoff said:
Why would you be surprised by this?

Because often, a lot of things to do with mingw and gcc don't work, or are
badly documented. (By badly documented, I also mean so much documentation,
and so many versions etc, that the piece of information I need is impossible
to find.)

The previous version 4.8.1 also had an -m64 switch, but said 'hello.c:1:0:
sorry, unimplemented: 64-bit mode not compiled in:
#include <stdio.h>
^'

Other downloads say they need cygwin to run (and you download a huge
installation), then the gcc will fail to run due to some internal error. Or
you download a version, and it's doesn't have gcc.exe, only some set of exe
files with some very long complication names, some of them 0 bytes in size.
Or you download something called mingw-w64, and it turns out to be "...a
complete runtime environment for gcc to support binaries native to Windows
64-bit and 32-bit operating systems.", whatever that is when it's at home.

So, that's why I'm surprised.

(Although it turns out code optimisation isn't quite as good as the mingw
4.8.1 version, and the two seem to have trouble co-existing. It might also
mean there could be little point in compiling for 64-bits, especially if
everything just doubles up in size anyway: a key struct type I need seems
now to occupy 32 bytes instead of 16 bytes. I expected 64-bit mode to be
able to copy such a struct (to registers for example) in two operations
instead of four. Now it will be the same number, but takes up double the
bandwidth to boot! So some major tweaking will be needed.)

(To see how a compiler distribution should be done, have a look here for
example, http://www.smorgasbordet.com/pellesc/, and tell me if you can make
it any more obvious whether you're downloading a 32 or 64-bit version of a
compiler. Compare that with the 'maze of twisty little passages' that is
mingw and sourceforge.)
 
D

David Brown

I'm not disputing /a/ version of gcc generating 64-bit code exists. I was
asking, if Jorgen had such a compiler, if he knew where I could download a
copy. However I forgot that he was probably talking a non-Windows version.

amd64-bit versions of gcc have existed for longer than amd64 processors
- gcc was used while the chips were still being simulated. But you are
right that this was not for windows - windows always makes things more
difficult for development.

But a google for "gcc windows 64" turns up
 
J

James Harris

Richard said:
....


What total and utter tosh.

LOL - always good to hear a reasoned argument well made. ;-) Would explain
but it's off topic for this newsgroup so let's not go there. I was just
disagreeing with the comment which pinned the blame for complexity on the C
compiler.

James
 
B

BartC

David Brown said:
On 15/02/14 23:26, BartC wrote:

amd64-bit versions of gcc have existed for longer than amd64 processors -
gcc was used while the chips were still being simulated. But you are
right that this was not for windows - windows always makes things more
difficult for development.

But a google for "gcc windows 64" turns up
<http://mingw-w64.sourceforge.net/> , which looks like a pretty good bet.

It does look like a good bet, but you'd lose:

"Mingw-w64 delivers runtime, headers and libs for developing both 64 bit
(x64) and 32 bit (x86) windows applications using GCC and other free
software compilers."

It doesn't include the actual compiler, afaics, unless it's very well
hidden. (Actually I have little idea exactly what this product is for.)

You'd think they would make it more obvious *and* put a very clear link to
the corresponding 64-bit gcc compiler. But the official mingw gcc release
4.8.1, when you eventually make your own way to it, doesn't support 64-bit
code generation. This is something that you have to discover for yourself
however.

It doesn't help either that this Windows-targeted binary file is in .tar.bz2
format!
 
D

David Brown

It does look like a good bet, but you'd lose:

"Mingw-w64 delivers runtime, headers and libs for developing both 64 bit
(x64) and 32 bit (x86) windows applications using GCC and other free
software compilers."

It doesn't include the actual compiler, afaics, unless it's very well
hidden. (Actually I have little idea exactly what this product is for.)

You'd think they would make it more obvious *and* put a very clear link
to the corresponding 64-bit gcc compiler. But the official mingw gcc
release 4.8.1, when you eventually make your own way to it, doesn't
support 64-bit code generation. This is something that you have to
discover for yourself however.

It doesn't help either that this Windows-targeted binary file is in
.tar.bz2
format!

There are several parts that make up a toolchain - the compiler is only
one of them. gcc is a compiler that supports win64 directly, both as a
host and as a target. But the compiler itself is not sufficient to make
useful programs on a particular platform - for that, you need the
libraries, runtime, and headers for that platform's API and system
interfaces. gcc is the compiler - it does not provide these parts for
any target. On Linux (and other *nix), it's easy - such libraries and
headers are part of the standard installation for a *nix system. But
Windows has never been developer-friendly in that way, and does not
include any of that stuff (it has some parts of a limited C library in
dll form, but not as a statically linkable library and no headers). It
is this part of the toolchain that mingw-64 provides for Win64 and Win32.

In addition, keeping up with Windows can be a tough game for a compiler
- things change every now and again. Sometimes that means changes need
to be made in the compiler itself. It can take time for such changes to
make their way into the mainline gcc tree and new gcc source releases -
mingw-64 therefore keep track of any necessary patches and changes for
the newest support, and make them available while they are still working
their way through the mainline gcc development process. (Many big Linux
distributions do the same, as do most embedded targets for gcc.)

So when you download a "release" from mingw-64, it contains the
libraries, headers, and runtimes for using gcc on Win32 and Win64, along
with any useful outstanding patches to gcc itself. It does not contain
the compiler - you can download that and build it yourself, as this is a
source code release.

Alternatively, you could spend a couple of minutes reading the wiki and
find your way to the 64-bit binaries.


I'll certainly agree that it is not as easy or obvious as it could be.
But it does not look to be /that/ hard. (The only Windows installation
I have is an old 32-bit XP system, so I have not tried it myself.)

One thing to remember, however, is that you should always install
different compilers and different versions of compilers in different
directories. And ignore any advice about changing paths - or at least,
limit the change to a local change in a command prompt and not a global
change.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top