Problems with QNX 6.2.1: va_arg works incorrectly...

look at this simple code. As you see, it should work:

void
test(const char *str1, short num1, …) {
const char *str2;
va_list argv;
va_start(argv, num1);
str2 = va_arg(argv, const char *);
printf("%s %d %s\n", str1, num1, str2);
va_end(argv);
}
int
main(int argc, char *argv[]) {
test(“A”, 1, “B”);
return 0;
}

this program should run, surely. it does it with linux, win32 or any
other os. but, it fails under QNX!

This program does SIGSEGV on my qnx 6.2.1 NC. either with gcc or qcc.
It’s my hands or it is really a bug?

Anyone, please, try to gcc it and tell me, it is I who wrong or QNX
team?

Ilyak:

I tried it with gcc_ntox86, and it does indeed crash. va_arg(argv, const
char *) returns an out-of-bounds pointer. If I instead use

void test(const char *str1, int num1, …)

it works! I looked at the <x86/platform.h> header file and, if I understand
the macros, __va_arg(ap,type) should work with a short type as well.

Note that PC-lint gives warning 579 for your prototype for test:

void test(const char *str1, short num1, …)

“parameter preceding ellipsis has invalid type – When an ellipsis is
used, the type preceding the ellipsis should not be a type that would
undergo a default promotion such as char, short or float. The reason is
that many compiler’s variable argument schemes (using stdarg.h) will break
down.”

Clearly this warning has merit :slight_smile: The reason, however, eludes me.

->>>–Sherwood–>
New York Air Brake Corp.

“Ilyak Kaznacheev” <ilyak@online.ru> wrote in message
news:5g3revcfl9eldl2vshtmi9cfdnu14crk3i@4ax.com

look at this simple code. As you see, it should work:

void
test(const char *str1, short num1, …) {
const char *str2;
va_list argv;
va_start(argv, num1);
str2 = va_arg(argv, const char *);
printf("%s %d %s\n", str1, num1, str2);
va_end(argv);
}
int
main(int argc, char *argv[]) {
test(“A”, 1, “B”);
return 0;
}

this program should run, surely. it does it with linux, win32 or any
other os. but, it fails under QNX!

This program does SIGSEGV on my qnx 6.2.1 NC. either with gcc or qcc.
It’s my hands or it is really a bug?

Anyone, please, try to gcc it and tell me, it is I who wrong or QNX
team?

“parameter preceding ellipsis has invalid type – When an ellipsis is
used, the type preceding the ellipsis should not be a type that would
undergo a default promotion such as char, short or float. The reason is
that many compiler’s variable argument schemes (using stdarg.h) will break
down.”

Because the standard says that is the case? :wink: Basically the last arg
before the … has to be an int or a type that will not change in size
if cast to an int. It’s in the ANSI/ISO standard. Actually, it says
the behavior is undefined if it is promoted. So it will depend on the
compiler and the libc.

chris


Chris McKillop <cdm@qnx.com> “The faster I go, the behinder I get.”
Software Engineer, QSSL – Lewis Carroll –
http://qnx.wox.org/

Chris:

Yes, I see that this was already answered (weeks ago) in a duplicate
submission to qdn.public.devtools. Oh, well…guess I need to search all
the newsgroups before I spend time replying to something :-/

Simply changing the function as shown below works fine, so there will be no
problem porting my variable-arg functions when the time comes to do so. I
suppose I may never understand why Ilyak’s original function did not work.
But had I tried to write code like that, PC-lint would have complained, I
would have sheepishly said, “Oh, okay,” then I would have rewritten it just
to make lint shut up :slight_smile:

void test(const char *str1, …)
{
const char *str2;
short num1;
va_list argv;
va_start(argv, str1);
num1 = va_arg(argv, short);
str2 = va_arg(argv, const char *);
printf("%s %d %s\n", str1, num1, str2);
va_end(argv);
}

->>>–Sherwood–>
New York Air Brake Corp.

“Chris McKillop” <cdm@qnx.com> wrote in message
news:bdj4ou$lcj$1@nntp.qnx.com

“parameter preceding ellipsis has invalid type – When an ellipsis
is
used, the type preceding the ellipsis should not be a type that would
undergo a default promotion such as char, short or float. The reason is
that many compiler’s variable argument schemes (using stdarg.h) will
break
down.”


Because the standard says that is the case? > :wink: > Basically the last arg
before the … has to be an int or a type that will not change in size
if cast to an int. It’s in the ANSI/ISO standard. Actually, it says
the behavior is undefined if it is promoted. So it will depend on the
compiler and the libc.

chris


Chris McKillop <> cdm@qnx.com> > “The faster I go, the behinder I get.”
Software Engineer, QSSL – Lewis Carroll –
http://qnx.wox.org/