473,902 Members | 5,842 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

va_arg and short

I was compiling a program written by someone else about six years ago, and
widely distributed at the time. It also includes makefiles for many
different systems, so I know it has been compiled with many different
compilers.

I got compile errors when it used va_arg to fetch an argument of type short.
That seemed a little strange to me, so I changed it to int and it compiled
just fine.

So now I wonder, just what is the rule for va_arg and short? It would seem
strange to reject certain types, yet that is what the compiler did.

-- glen
Nov 13 '05
99 9142
"Douglas A. Gwyn" wrote:

Dan Pop wrote:
Thanks. Has anyone actually did it this way in *real* C code?


Most programmers don't try to create objects so large that
they have to worry about SIZE_MAX. If you do have to worry,
use a method like what Francis showed.


Many of the programs I've work on over the past 20 years have pushed the
limit on available memory, and in several cases they pushed the limit on
what C99 would call SIZE_MAX (though most of them have been C90
programs). I have no idea how common that is; it may be more common in
the kind of applications I work on than in other kinds you're more
familiar with.
Nov 13 '05 #81
In article <8x*********@kh ms.westfalen.de >,
kaih=8x******** *@khms.westfale n.de (Kai Henningsen) wrote:
ch***********@c bau.freeserve.c o.uk (Christian Bau) wrote on 02.11.03 in
<ch************ *************** ******@slb-newsm1.svr.pol. co.uk>:
In article <aE0pb.81932$HS 4.680953@attbi_ s01>,
"Glen Herrmannsfeldt" <ga*@ugcs.calte ch.edu> wrote:
I was compiling a program written by someone else about six years ago,
and
widely distributed at the time. It also includes makefiles for many
different systems, so I know it has been compiled with many different
compilers.

I got compile errors when it used va_arg to fetch an argument of type
short. That seemed a little strange to me, so I changed it to int and it
compiled just fine.

So now I wonder, just what is the rule for va_arg and short? It would
seem strange to reject certain types, yet that is what the compiler did.
When you use the va_arg macro, the type that you supply must (with some
exceptions that don't apply here) match the type of the actual argument
_after default promotions_.

Any argument of type short would be promoted to int, so using short in
the va_arg macro can never match the type of the actual argument after
default promotions.


A conforming implementation could have short == int, though, in which case
short would be just fine to use.


No, you can't have short == int. You can have sizeof short == sizeof
int, you can have SHORT_MAX == INT_MAX etc., but you cannot have short
== int.
Once there were quite a large number of implementations for which this was
true.


You would still have undefined behavior. A program producing undefined
behavior may produce exactly the behavior you expect, but it is still
undefined behavior.
Nov 13 '05 #82
On Tue, 11 Nov 2003 08:40:02 GMT, "Glen Herrmannsfeldt"
<ga*@ugcs.calte ch.edu> wrote:

"Douglas A. Gwyn" <DA****@null.ne t> wrote in message
news:gd******** ************@co mcast.com...
Glen Herrmannsfeldt wrote: <attribution uncertain>
What do you do on those unfortunate systems where pointers can address
memory much larger than size_t?

Well, that is a good question. Maybe 16 bit int is long past, and we
shouldn't worry about the problem. Though with 32 bit int and memories
larger than 4GB maybe we should. Consider a machine with 64 bit pointers,
but 32 bit int. You could still increment the pointer multiple times, less
than 2GB each time. Now, reasonably likely the machine would also have a
64 bit long or long long, but maybe doesn't supply the ability to increment
pointers (or subscript arrays) with them.
Then it's nonconforming. Pointer arithmetic is defined for any integer
type (in C99 including any implementation-defined 'extended' types)
not just 'int'. But only within one declared or allocated object,
whose size apparently can be bounded by size_t -- especially if, say,
the actual address space usable without thrashing is only say 10GB,
even though represented in a 64bit format, and address calculations
using >32bit offset are more costly, it might well be a reasonable
tradeoff to support only 4G-1B objects in that address space, and
*then* only subscripting/offseting by up to that. Or maybe even 2G-1B,
so ptrdiff_t can be 32bit signed.

<snip> Well, the argument of fseek() and the return from ftell() were long (or even
int?) many years before 4GB of memory was affordable, real or virtual. It
looks like a mistake now, and then we have things like fseek64() and
ftell64().

More to the point, before 4GB in a single disk; or really filesystem,
which then was at most one disk. Heck, 6ed Unix ran on a system with
5*M*B of disk (2 x RK05, and that's cartridge not the wuss -F).
- David.Thompson1 at worldnet.att.ne t
Nov 13 '05 #83
Dave Thompson wrote:
On Tue, 11 Nov 2003 08:40:02 GMT, "Glen Herrmannsfeldt"
(snip)
Well, that is a good question. Maybe 16 bit int is long past, and we
shouldn't worry about the problem. Though with 32 bit int and memories
larger than 4GB maybe we should. Consider a machine with 64 bit pointers,
but 32 bit int. You could still increment the pointer multiple times, less
than 2GB each time. Now, reasonably likely the machine would also have a
64 bit long or long long, but maybe doesn't supply the ability to increment
pointers (or subscript arrays) with them.

Then it's nonconforming. Pointer arithmetic is defined for any integer
type (in C99 including any implementation-defined 'extended' types)
not just 'int'. But only within one declared or allocated object,
whose size apparently can be bounded by size_t -- especially if, say,
the actual address space usable without thrashing is only say 10GB,
even though represented in a 64bit format, and address calculations
using >32bit offset are more costly, it might well be a reasonable
tradeoff to support only 4G-1B objects in that address space, and
*then* only subscripting/offseting by up to that. Or maybe even 2G-1B,
so ptrdiff_t can be 32bit signed.


Can an implementation have 64 bit pointers, but no integer type longer
than 32 bits?

How do you make a constant of type size_t?

-- glen

Nov 13 '05 #84
In <apkvb.201767$9 E1.1076919@attb i_s52> glen herrmannsfeldt <ga*@ugcs.calte ch.edu> writes:
Can an implementation have 64 bit pointers, but no integer type longer
than 32 bits?
Yes, of course, as far as C89 is concerned. C99 requires long long to be
at least 64-bit.
How do you make a constant of type size_t?


You don't. But you can have a constant expression of type size_t and
constant expressions can be used instead of constants anywhere. E.g.
a C89 program can define SIZE_MAX as (size_t)-1.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #85
glen herrmannsfeldt wrote:
.... snip ...
Can an implementation have 64 bit pointers, but no integer type
longer than 32 bits?


Of course. You see it every day on your garden variety x86
machines. Every pointer involves a segment register value, all of
which just happen to be set the same, and thus effectively
ignored.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 13 '05 #86
glen herrmannsfeldt <ga*@ugcs.calte ch.edu> writes:
How do you make a constant of type size_t?


(size_t) 100

--
Micah J. Cowan
mi***@cowan.nam e
Nov 13 '05 #87
In article <3F************ ***@yahoo.com>,
CBFalconer <cb********@wor ldnet.att.net> wrote:
Of course. You see it every day on your garden variety x86
machines. Every pointer involves a segment register value, all of
which just happen to be set the same, and thus effectively
ignored.


That's silly. You might as well say that all pointers include the
page table. The implementation of dereferencing pointers involves the
segment registers, but they are not part of the pointer. If they were,
you'd be able to alter a pointer to include a different segment
register - by abuse of pointers to pointers, or by using a debugger -
and you can't.

-- Richard
--
Spam filter: to mail me from a .com/.net site, put my surname in the headers.

FreeBSD rules!
Nov 13 '05 #88
Richard Tobin wrote:
CBFalconer <cb********@wor ldnet.att.net> wrote:
Of course. You see it every day on your garden variety x86
machines. Every pointer involves a segment register value, all of
which just happen to be set the same, and thus effectively
ignored.


That's silly. You might as well say that all pointers include the
page table. The implementation of dereferencing pointers involves the
segment registers, but they are not part of the pointer. If they were,
you'd be able to alter a pointer to include a different segment
register - by abuse of pointers to pointers, or by using a debugger -
and you can't.


Yes you can. Just use a debugger that can alter the segment
registers and operates at machine code level. Just before a
dereference alter the implied segment register for that
instruction.

For a safer simulation just use some compact model MSDOS code
under debug, and alter the segment registers. Just because people
have gone to great lengths to hide the unpleasant truths from you
doesn't mean they don't exist.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 13 '05 #89
In article <3F************ ***@yahoo.com>,
CBFalconer <cb********@wor ldnet.att.net> wrote:
Yes you can. Just use a debugger that can alter the segment
registers and operates at machine code level. Just before a
dereference alter the implied segment register for that
instruction.


And integers are all 33 bits. Just before an addition, alter the
carry flag.

-- Richard
--
Spam filter: to mail me from a .com/.net site, put my surname in the headers.

FreeBSD rules!
Nov 13 '05 #90

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
2282
by: Niels Dekker (no reply address) | last post by:
Is it possible for a standard compliant C++ compiler to have ( sizeof(short) < sizeof(int) ) and ( sizeof(short) == sizeof((short)0 + (short)0) ) ? Regards, Niels Dekker http://www.xs4all.nl/~nd/dekkerware
34
16717
by: Andy | last post by:
Hi, Are 1 through 4 defined behaviors in C? unsigned short i; unsigned long li; /* 32-bit wide */ 1. i = 65535 + 3; 2. i = 1 - 3; 3. li = (unsigned long)0xFFFFFFFF + 3; 4. li = 1 - 3;
8
1703
by: NilsNilsson | last post by:
I wrote this: short s1 = 0; short s2 = 1; short s3 = s1 + s2; And gor this compile error message: Cannot implicitly convert type 'int' to 'short' What is wrong here?
8
16421
by: Ken Dopierala Jr. | last post by:
Hi, I'm reading the header file of a PCX image and I need to convert 2 bytes to a short. How would I go about doing this? I know that they are bytes 8 & 9 in my byte array. I'm not sure how to take those two and convert them into a short though. In C I would just use a union and assign them accordingly. Thanks! Ken.
15
8465
by: Steffen Loringer | last post by:
Hi, I'm using the following function to join 2 char (byte) into one short on a 32 bit X86 platform: unsigned short joinUnsigShort(unsigned char a,unsigned char b) { unsigned short val = 0; val = a; val <<= 8;
4
5227
by: slougheed | last post by:
I encountered a problem after we had converted our declarations of 'unsigned short int' to uint16_t. In one instance, whoever did the conversion failed to delete the 'short' keyword so we had a 'uint16_t short'. The compiler (GNU 3.3.5) allows this but ignores the original unsigned keyword and initialzes the variable as a signed short int. I created a very simple test program just to see what was happening: #include <stdio.h> ...
10
5665
by: Jim Langston | last post by:
Is the following well defined? size_t IntVal = 65537; unsigned short Length; if ( IntVal static_cast<unsigned short>( -1 ) ) { std::cout << "Value too long to fit in a short" << std::endl; } else
10
5460
by: nyhetsgrupper | last post by:
The following code result in the following compilation error: Error 1 Cannot implicitly convert type 'int' to 'short'. An explicit conversion exists (are you missing a cast?) short a = 1; short b = 2; short result = a + b; Can anyone explain why??
3
6414
by: mathieu | last post by:
Could someone please tell me what is wrong with the following -ugly- piece of c++ code. Why when I explicititely set the template parameter my gcc compiler start getting confused: bla.cxx: In function 'int main()': bla.cxx:25: error: call of overloaded 'foo(short unsigned int*&)' is ambiguous bla.cxx:2: note: candidates are: void foo(OutputType*) bla.cxx:10: note: void foo(PixelType*)
0
9997
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
9845
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11279
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10981
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10499
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7205
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
6085
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4725
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4306
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.