473,899 Members | 3,641 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 9141
Brian Inglis wrote:

On Mon, 03 Nov 2003 10:17:18 -0700 in comp.std.c, Thad Smith
<th*******@acm. org> wrote:
Peter Nilsson wrote:
I wonder why va_arg could not accept a type subject to promotion and
handle them accordingly, i.e. accept the promoted type implicitly and
convert it to the original/requested type. [So, cases like the
character types and unsigned short, which might promote to signed or
unsigned int, could be handled without having to resort to integer
limit checks.]


While the programmer should know that the type char and short are
promoted, what about int32_t? Can it be an argument of va_arg? It
might be equivalent to a short (needing promotion), or a int or a long.
Is there any way of portably accessing a variadic int32_t (or intX_t for
X >= 16) parameter?


A long is guaranteed to hold at least the same values as an
int32_t, int and short may not. A short is guaranteed to hold at
least the same values as an int16_t. A signed char is guaranteed
to hold at least the same values as an int8_t. There are no other
guarantees AFAIR.


That means that the only signed integral types you can be certain won't
be promoted to 'int' are 'long' and 'long long', and similarly for
unsigned types. That causes a lot of portability problems when trying to
pass the size-named types to a variadic function. It also causes similar
problems when trying to pass them to functions declared without a
prototype, but that's easy to fix: just provide a prototype.
Nov 13 '05 #21
ai***@acay.com. au (Peter Nilsson) wrote in message news:<63******* *************** ****@posting.go ogle.com>...
ku****@wizard.n et (James Kuyper) wrote in message news:<8b******* *************** ****@posting.go ogle.com>...
ai***@acay.com. au (Peter Nilsson) wrote in message news:<63******* *************** ****@posting.go ogle.com>...
[Cross posted to comp.std.c.] .... I wonder why va_arg could not accept a type subject to promotion and
handle them accordingly, i.e. accept the promoted type implicitly and
convert it to the original/requested type. [So, cases like the
character types and unsigned short, which might promote to signed or
unsigned int, could be handled without having to resort to integer
limit checks.]

What sorts of architectures would make such an alternative va_arg
behaviour difficult to implement in practice?


The normal va_arg() macro can, on many platforms, expand to normal C
code. On some platforms, something like the following is sufficient:

typedef char* va_list;
#define va_start(arg) )(&arg+sizeof(a rg))


#define va_start(ap,arg ) ((ap) = (char *) &arg) /* ? */
#define va_arg(ap,type) ((type*)(ap+=si zeof(type)))[-1]
#define va_end(ap)

Try to figure out how to modify that without using any extensions to C
such as sizeof(promoted _typeof(type)). An implementation is free, of
course, to use extensions, but I think that the committee would resist
changing the specification in a way that would make the use of an
extension mandatory.


The 'extension' is static type analysis, indeed, the *same* analysis
used to promote parameters in variadic function calls in the first
place.


You'll have to explain that to me. Note: the above C code contains the
full definition of the <stdarg.h> for that platform; no C compiler
magic is needed, no special handling of code that contains va_arg().
It simply expands to C code which is interpreted in exactly the same
fashion that it would be if it were written by the user. The only
thing unportable about it is the assumptions it embodies about the
argument passing conventions.

Are you saying that static type analysis will somehow make the above
definitions work properly when given the original type of the
argument, rather than the promoted type? I don't see how that could
be: va_arg(ap,short ) would seem to be incrementing ap by the wrong
amount, and using an lvalue with the wrong type to retrieve the value
it points at. I don't see how static type analysis can handle that.

Or are you saying that the above definitions can be re-written without
using implementation-specific extensions (of the syntax kind, not the
"static type analysis" kind) or compiler magic to produce the right
result? If so, could you give use the re-write?
Nov 13 '05 #22
ai***@acay.com. au (Peter Nilsson) wrote in message news:<63******* *************** ****@posting.go ogle.com>...
Thad Smith <th*******@acm. org> wrote in message news:<3F******* ********@acm.or g>... ....
Is there any way of portably accessing a variadic int32_t (or intX_t for
X >= 16) parameter?


A tedious one...

#if INT32_MAX <= INT_MAX


Almost:

#if INT32_MAX <= INT_MAX && INT32_MIN >= INT_MIN
int32_t x = va_arg(ap, int);
#else
int32_t x = va_arg(ap, int32_t);
#endif

Nov 13 '05 #23
Oops! I missed one item; I should have included it in my previous
message:

ai***@acay.com. au (Peter Nilsson) wrote in message news:<63******* *************** ****@posting.go ogle.com>...
ku****@wizard.n et (James Kuyper) wrote in message news:<8b******* *************** ****@posting.go ogle.com>...

....
#define va_start(arg) )(&arg+sizeof(a rg))


#define va_start(ap,arg ) ((ap) = (char *) &arg) /* ? */


Sorry, that got messed up somehow, but your replacement is not the
correct fix. It should have been:

#define va_start(arg) ((char*)(&arg+s izeof(arg))
Nov 13 '05 #24
On 4 Nov 2003 11:10:30 -0800, ku****@wizard.n et (James Kuyper) wrote:
Oops! I missed one item; I should have included it in my previous
message:

ai***@acay.com .au (Peter Nilsson) wrote in message news:<63******* *************** ****@posting.go ogle.com>...
ku****@wizard.n et (James Kuyper) wrote in message news:<8b******* *************** ****@posting.go ogle.com>...

...
> #define va_start(arg) )(&arg+sizeof(a rg))


#define va_start(ap,arg ) ((ap) = (char *) &arg) /* ? */


Sorry, that got messed up somehow, but your replacement is not the
correct fix. It should have been:

#define va_start(arg) ((char*)(&arg+s izeof(arg))


?

Do you mean ((char*)(&arg+1 ))?

Or perhaps (((char*)&arg)+ sizeof(arg))?

Regards,

-=Dave
--
Change is inevitable, progress is not.
Nov 13 '05 #25

"Dan Pop" <Da*****@cern.c h> wrote in message
news:bo******** **@sunnews.cern .ch...
In <DJCpb.99053$Fm 2.81929@attbi_s 04> "Glen Herrmannsfeldt" <ga*@ugcs.calte ch.edu> writes:
I don't disagree with that. This program is part of a widely distributed
program library, and I am sure has been compiled on many compilers over theyears. Most likely, this statement has never been executed, so it reallydoesn't matter what it compiles into. The problem comes when a program issupposed to be portable to a wide variety of machines and compilers, with
the expectation that it can be compiled and installed by non-C programmers.
A non-C programmer has no business using a C compiler or building and
installing C programs. Imagine that the compiler emits a warning
(something that the person who wrote the code cannot avoid, for *any* C
compiler). Without knowing C, how can you tell if the problem can be
safely ignored, or the resulting executable should not be used?
A good argument for the compile once, run anywhere system that Java uses.

Though some programs supply a set of test inputs and expected outputs
carefully selected to test as much of the program as possible. The only one
I can think of right now is TeX, though there are likely others.
Someone is supposed to be able to untar it, run make, and not have any
compiler or link errors. Even required diagnostics can be produced as "warnings" instead of
"errors", so the absence of compiler errors means exactly nothing.
And some systems will let you link and run a program, even with compiler
errors.
Considering that it passed so many compilers on
the way, would it have been reasonable to make it a warning? When the code is obviously broken, an error is much better. Far too many
people blissfully ignore the warnings... The next error I ran into, in a different library, came from not finding theinclude file ndbm.h. It seems that it is now db.h, at least on the systemthat I was using.

Another argument for having a C programmer building C programs. Similar
issues arise with -lcurses vs -lncurses at link time. Again obvious for
the C programmer and totally insurmountable for the non-C programmer.


Well, yes. Though different amounts of experience will be necessary for
different problems.

-- glen
Nov 13 '05 #26
Dan Pop wrote:
If I multiply two size_t values, do I get undefined behaviour in case of
overflow or the result modulo SIZE_MAX? It depends on whether size_t is
subject to the integral promotions or not, an issue the standard is
not addressing at all.


If size_t is being used properly, the question should never arise.

Nov 13 '05 #27
On Tue, 04 Nov 2003 17:09:51 -0500,
Douglas A. Gwyn <DA****@null.ne t> wrote
in Msg. <6e************ ********@comcas t.com>
Dan Pop wrote:
If I multiply two size_t values, do I get undefined behaviour in case of
overflow or the result modulo SIZE_MAX? It depends on whether size_t is
subject to the integral promotions or not, an issue the standard is
not addressing at all.


If size_t is being used properly, the question should never arise.


What do you mean by "used properly", and how does this proper usage avoid
the question of overflow?

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 13 '05 #28
On 4 Nov 2003 15:33:56 GMT,
Dan Pop <Da*****@cern.c h> wrote
in Msg. <bo**********@s unnews.cern.ch>
A non-C programmer has no business using a C compiler or building and
installing C programs.


This is getting off-topic.

A normal computer user has plenty of business installing any kind of
programs though. There might be a C compiler under the hood of --say-- the
popular GNU "./configure && make && su root make install" mechanism, or
there might be some "Windows InstallShield" program at work. Both
approaches work fine most of the time, and, in my experience, both have
plenty of potential of installing broken an incomplete software, or of not
working at all. What difference does it make to a non-C-programmer? In
both cases, some obscure piece of software just fucks up.

(in the case of the C source code distribution, however, the C programmer
has a chance to have a go at the underlying problem which usually leads to
unjustifiable amounts of time spent on fixing it.)

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 13 '05 #29
"James Kuyper" <ku****@wizard. net> wrote in message
news:8b******** *************** ***@posting.goo gle.com...
ai***@acay.com. au (Peter Nilsson) wrote in message news:<63******* *************** ****@posting.go ogle.com>...
Thad Smith <th*******@acm. org> wrote in message news:<3F******* ********@acm.or g>... ... Is there any way of portably accessing a variadic int32_t (or intX_t for X >= 16) parameter?


A tedious one...

#if INT32_MAX <= INT_MAX


Almost:

#if INT32_MAX <= INT_MAX && INT32_MIN >= INT_MIN


I thought about that, but same signed types cannot overlap ranges. So even
taking your argument that INT_MAX need not be one less than a power of two
into acount, a programmer should only need to check one bound.

Unless I'm missing something?

--
Peter
Nov 13 '05 #30

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
11272
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...
0
10863
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10971
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
10494
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
9666
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7201
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
5887
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4720
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

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.