Compile errors?

J

jacob navia

Le 17/02/2014 17:21, David Brown a écrit :
That depends on your platform - 64-bit has been the default for many
years in Linux, both for the system itself and for the applications.
But 64-bit windows has only been the default for new windows systems for
a few years, and though I don't have the figures, I expect it is still
in the minority for current installations.

Since windows XP 64, presented in April 2005 to the public, windows has
been 64 bits. Next april will be NINE years then, that windows is using
64 Bit code. I do not count the versions of windows for the 64 bit DEC
Alpha, from 2001 or the 2001 version of Windows NT for Itanium.

Indeed, you do not have the figures...
 
G

Geoff

Thanks. But it says: "Installing MinGW-builds: Cannot download
repository.txt".
I've seen that complaint on the support forums for it. Not sure what
the solution is, I had no trouble installing it twice. (See below.)
Besides this is unlike any other thing I've tried to download, and I don't
think that changes my conclusion that whatever the mingw-w64 was that I
downloaded, it didn't include an actual compiler. The fact that there are so
many different sources, different builds and installers and sites and
everything, is one of the things that makes it all so complicated.

I agree. There always seems to be a lot of hand waving and
conditionals to installation of open-source stuff, especially among
the various Linux distros. Package management is a pain.

This was code from Plauger's "The Standard C Library" and was his test
I'm not sure that that indicates this is actual 64-bit code (it probably is,
if you used -m64 and it didn't complain); I suspect you'd get the same
values with -m32. UINTPTR_MAX is a better indicator.

It was 64 bit and it didn't complain. However, I must confess the
package above doesn't actually use the -m64 or -m32 switches. I
expected the 64 bit compiler to generate 32 bit code with the -m32
switch but it complained like crazy. Unfortunately UINTPTR_MAX is not
a good indicator of 64-bit capability since it will depend on whether
the implementation is up to date or not. <stdint.h> in the Microsoft
64 bit compiler is wrong about UINT32_MAX, making it no bigger than
UINT32_MAX even though it reports sizeof(int*) correctly as 8 in 64
bit vs 4 in the 32 bit version.

I actually had to install the package a second time with the x86
architecture selected in order to get the 32 bit compiler. What you
end up with is two shortcuts to two environments, one for 32 bits and
one for 64 bits. Not a very good solution.

Both the 32-bit and 64-bit MinGW compilers report UINTPTR_MAX is
4294967295 so I don't understand your preference for referring to that
constant.
 
I

Ian Collins

jacob said:
Le 17/02/2014 17:21, David Brown a écrit :

Since windows XP 64, presented in April 2005 to the public, windows has
been 64 bits.

But was it the default?

I could enter the OS dick swinging contest by adding Solaris and its
derivatives have never needed separate 64 and 32 bit versions, but that
would spoil the fun.
 
B

BartC

Geoff said:
It was 64 bit and it didn't complain. However, I must confess the
package above doesn't actually use the -m64 or -m32 switches. I
expected the 64 bit compiler to generate 32 bit code with the -m32
switch but it complained like crazy. Unfortunately UINTPTR_MAX is not
a good indicator of 64-bit capability since it will depend on whether
the implementation is up to date or not. <stdint.h> in the Microsoft
64 bit compiler is wrong about UINT32_MAX, making it no bigger than
UINT32_MAX even though it reports sizeof(int*) correctly as 8 in 64
bit vs 4 in the 32 bit version.

I actually had to install the package a second time with the x86
architecture selected in order to get the 32 bit compiler. What you
end up with is two shortcuts to two environments, one for 32 bits and
one for 64 bits. Not a very good solution.

Both the 32-bit and 64-bit MinGW compilers report UINTPTR_MAX is
4294967295

I can switch between 7 C compilers on my IDE, four 32-bit and three 64-bit.
The three 64-bit ones report it as 0xFFFFFFFFFFFFFFFF (although one of
those, lccwin64, originally reported it as 0xFFFFFFFF but the author
suggested I just put in the correct value.)

One compiler is the official mingw gcc 4.8.1, which although can't compile
64-bits, has the value of UINTPTR_MAX as 0xFFFFFFFFFFFFFFFF when _WIN64 is
defined. (The actual 64-bit gcc I now use is TDM-GCC, which gives the right
value. It's include files are highly convoluted however so it would have
been difficult to plug in the right value)
so I don't understand your preference for referring to that
constant.

I saw it on stackoverflow.com. Other answers were to use things like
__x86_64__ and __LP64__, which are specific to certain compilers.

But shouldn't UINTPTR_MAX tell you the size of an int needed to contain a
pointer? If it reports the wrong value, that sounds like a bug to me.
 
K

Keith Thompson

glen herrmannsfeldt said:
Did anyone ever consider adding internal functions to C?

Not to my knowledge. Since an "internal" function is easy to detect at
compile time (declared static and never has its address taken within the
translation unit in which it's defined), it's probably not worthwhile to
make it a language feature.

It occurs to me that inlining is a (rather drastic) modification of the
calling convention. The set of functions that can be inlined is
probably about the same as the set of functions that can be called with
a non-standard (and perhaps more efficient) calling convention.
 
J

jacob navia

Le 17/02/2014 22:39, BartC a écrit :
(although one of
those, lccwin64, originally reported it as 0xFFFFFFFF but the author
suggested I just put in the correct value.)

I fixed that yesterday. It is really not that difficult to see that it
was an error, that's why I told you to fix it.

I have started to work in the other bug you reported by the way
 
J

James Kuyper

....
I can switch between 7 C compilers on my IDE, four 32-bit and three 64-bit.
The three 64-bit ones report it as 0xFFFFFFFFFFFFFFFF (although one of
those, lccwin64, originally reported it as 0xFFFFFFFF but the author
suggested I just put in the correct value.)

One compiler is the official mingw gcc 4.8.1, which although can't compile
64-bits, has the value of UINTPTR_MAX as 0xFFFFFFFFFFFFFFFF when _WIN64 is
defined. (The actual 64-bit gcc I now use is TDM-GCC, which gives the right
value. It's include files are highly convoluted however so it would have
been difficult to plug in the right value)


I saw it on stackoverflow.com. Other answers were to use things like
__x86_64__ and __LP64__, which are specific to certain compilers.

But shouldn't UINTPTR_MAX tell you the size of an int needed to contain a
pointer? If it reports the wrong value, that sounds like a bug to me.

UNITPTR_MAX tells you the maximum value of uintptr_t, which is closely
related to the minimum size for uintptr_t. If UINTPTR_T is #defined in
<stdint.h>, then uintptr_t is one of two different integer (not "int"!)
types (the other is intptr_t) for which it is guaranteed that you can
convert a pointer to that type and back again, with a result that
compares equal to the original.

If UINTPTR_MAX != (uintptr_t)(-1), there is indeed a bug - which might
be the result of using a given compiler with an incompatible version of
<stdint.h>. With the C compiler and the C standard library provided by
two different vendors, that's an easy problem to have. For which of the
cases that you described is that condition false?
 
G

Geoff

I saw it on stackoverflow.com. Other answers were to use things like
__x86_64__ and __LP64__, which are specific to certain compilers.

But shouldn't UINTPTR_MAX tell you the size of an int needed to contain a
pointer? If it reports the wrong value, that sounds like a bug to me.

Precisely my point. I noted your dialog with Jacob Navia about the
header but I would never presume to change an implementation header
without consulting with the implementer as in that case.

The Microsoft VS2010 implementation in my possession says UINTPTR_MAX
is 0xffffffff. What is the typical user to make of that? uintptr_t and
size_t in x64 mode are plainly 64 bit sizes but the header says
they're not.

I think I would use sizeof(int*) or sizeof(size_t) or
sizeof(uintptr_t) to get a clue about my pointer sizes rather than use
what appears to be a bug in the implementation of the standard header.
I must point out that n1570 7.20.2.4 states UINTPTR_MAX is 2^16-1 so
the header is "correct" per the C11 standard but this is the _minimum_
value it can be, not the actual size it can be in the implementation.
Jacob was quite correct to make it that value per the standard.
 
K

Keith Thompson

Geoff said:
It was 64 bit and it didn't complain. However, I must confess the
package above doesn't actually use the -m64 or -m32 switches. I
expected the 64 bit compiler to generate 32 bit code with the -m32
switch but it complained like crazy. Unfortunately UINTPTR_MAX is not
a good indicator of 64-bit capability since it will depend on whether
the implementation is up to date or not. <stdint.h> in the Microsoft
64 bit compiler is wrong about UINT32_MAX, making it no bigger than
UINT32_MAX even though it reports sizeof(int*) correctly as 8 in 64
bit vs 4 in the 32 bit version.

There must be a typo in that last sentence (you refer to UINT32_MAX
twice), but I'm not cetain what it is. Are you saying that UINTPTR_MAX
has the same value as UINT32_MAX, even though sizeof (int*) == 8? What
is sizeof(uintptr_t)?

[...]
 
J

James Kuyper

On 02/17/2014 05:14 PM, Geoff wrote:
....
Precisely my point. I noted your dialog with Jacob Navia about the
header but I would never presume to change an implementation header
without consulting with the implementer as in that case. ....
I must point out that n1570 7.20.2.4 states UINTPTR_MAX is 2^16-1 so
the header is "correct" per the C11 standard but this is the _minimum_
value it can be, not the actual size it can be in the implementation.

No, C11 says that UNITPTR_MAX is "maximum value of pointer-holding
unsigned integer type". The value 2^16 - 1 that is printed next to it is
explained by 7.20.2p2: "Its implementation-defined value shall be equal
to or greater in magnitude (absolute value) than the corresponding value
given below, with the same sign, except where stated to be exactly the
given value."
Jacob was quite correct to make it that value per the standard.

If the value his version of <stdint.h> gives to UINTPTR_MAX isn't "the
maximum value of pointer-holding unsigned integer type", then it's
non-conforming. The fact that the minimum permitted value is 2^16-1
doesn't justify using 2^16-1 if that isn't in fact the correct value.
 
K

Keith Thompson

BartC said:
But shouldn't UINTPTR_MAX tell you the size of an int needed to contain a
pointer? If it reports the wrong value, that sounds like a bug to me.

It tells you the upper bound (not the size) of an unsigned integer (not
"int") type that can hold a converted void* value without loss of
information.

And yes, if pointers are 64 bits and uintptr_max is 32, that's a bug.
It could be an error by the developers, a configuration error putting
together a compiler and standard headers into an implementation, or an
end-user configuration error (though if everyone upstream has done their
jobs that shouldn't happen).
 
G

Geoff

There must be a typo in that last sentence (you refer to UINT32_MAX
twice), but I'm not cetain what it is. Are you saying that UINTPTR_MAX
has the same value as UINT32_MAX, even though sizeof (int*) == 8? What
is sizeof(uintptr_t)?

It's a typo on my part copy-pasting.

UINTPTR_MAX is defined in Microsoft's <stdint.h> as 0xffffffff. This
is plainly wrong for x64.

sizeof(uintptr_t) yields 8 in x64 builds and 4 in Win32 mode.
 
B

BartC

The Microsoft VS2010 implementation in my possession says UINTPTR_MAX
is 0xffffffff. What is the typical user to make of that? uintptr_t and
size_t in x64 mode are plainly 64 bit sizes but the header says
they're not.

I think I would use sizeof(int*) or sizeof(size_t) or
sizeof(uintptr_t) to get a clue about my pointer sizes rather than use
what appears to be a bug in the implementation of the standard header.

I got the impression that you couldn't use sizeof() in an #if expression
otherwise sizeof(int*) would clearly be simpler. And trying it, it doesn't
seem to work.

I suppose it can be used in a if-else statement, and the compiler knows to
generate code for the one true branch. But for defining things such as
typedefs upon which later code depends, that starts to sound hairier than
trying to use UINTPTR_MAX!
 
K

Keith Thompson

James Kuyper said:
UNITPTR_MAX tells you the maximum value of uintptr_t, which is closely
related to the minimum size for uintptr_t. If UINTPTR_T is #defined in

You mean if UINTPTR_MAX is defined.
<stdint.h>, then uintptr_t is one of two different integer (not "int"!)
types (the other is intptr_t) for which it is guaranteed that you can
convert a pointer to that type and back again, with a result that
compares equal to the original.

That guarantee applies only to pointers of type void*, though I think it
would take a deliberately perverse compiler for it to fail for other
object pointer types. (There are no guarantees at all for function
pointer types.)
 
J

Jorgen Grahn

I agree. There always seems to be a lot of hand waving and
conditionals to installation of open-source stuff, especially among
the various Linux distros. Package management is a pain.

That doesn't make sense in context, unless you meant "/except/ among
the various Linux distros" -- this is an endless thread about how
difficult it is to do something on Windows which worked out of the box
on Linux, a decade ago.

/Jorgen
 
K

Keith Thompson

Geoff said:
It's a typo on my part copy-pasting.

UINTPTR_MAX is defined in Microsoft's <stdint.h> as 0xffffffff. This
is plainly wrong for x64.

sizeof(uintptr_t) yields 8 in x64 builds and 4 in Win32 mode.

Based on your description, that's clearly a bug -- and Microsoft doesn't
have the excuse of integrating a compiler and standard headers from
different sources. (They may have done so, but their name is on the
whole thing.)

A reasonable workaround might be:

#include <limits.h>

#ifdef SOME_SYMBOL
#undef UINTPTR_MAX
#define UINTPTR_MAX ((uintptr_t)-1)
#endif

except that this defeats the purpose of using UINTPTR_MAX in a #if
expression.

If there are preprocessor symbols that reliably determine whether the
current build has 32-bit or 64-bit pointers, you could do:

#include <limits.h>

#undef UINTPTR_MAX
#if THIS_IS_A_32_BIT_BUILD
#define UINTPTR_MAX 0xffffffff
#elif THIS_IS_A_64_BIT_BUILD
#define UINTPTR_MAX 0xffffffffffffffff
#else
#error "I'm so confused!"
#endif
 
G

Geoff

That doesn't make sense in context, unless you meant "/except/ among
the various Linux distros" -- this is an endless thread about how
difficult it is to do something on Windows which worked out of the box
on Linux, a decade ago.

No, I mean it's a pain even in current Linux distributions. It didn't
work out of the box on Linux a decade ago and it still doesn't work
out of the box. If it worked out of the box we wouldn't be on Fedora
20 or Ubuntu 12.0 or a dozen other flavors of double-digit revision
with a multitude of configs and switches to worry about when deploying
those platforms.
 

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

Forum statistics

Threads
474,075
Messages
2,570,562
Members
47,197
Latest member
NDTShavonn

Latest Threads

Top