🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Marv Graham Wed, 29 Jul 1992 16:48
2.2.2 stdio.h <=> stdarg.h problem
#324
Author: Marv Graham
Date: Wed, 29 Jul 1992 16:48
163 lines
4130 bytes
On OSF i386 systems, the standard /usr/include/stdio.h contains the lines

/*
 * (c) Copyright 1990, 1991, OPEN SOFTWARE FOUNDATION, INC.
 * ALL RIGHTS RESERVED
 */
/*
 * OSF/1 Release 1.0.1
 */
/* @(#)$RCSfile: stdio.h,v $ $Revision: 2.11.4.3 $ (OSF) $Date: 91/03/11 15:02:20 $ */
/*
 * COMPONENT_NAME: stdio.h
 *                                                                    
 * ORIGIN: IBM
 *
 * Copyright International Business Machines Corp. 1985, 1988
 * All Rights Reserved
 * Licensed Material - Property of IBM
	...
	...
	...
#ifndef _VA_LIST
#define _VA_LIST
typedef char * __va_list;
extern int  vfprintf(FILE *, const char *, __va_list );
extern int  vprintf(const char *, __va_list );
extern int  vsprintf(char *, const char *, __va_list );
#else
extern int  vfprintf(FILE *, const char *, va_list );
extern int  vprintf(const char *, va_list );
extern int  vsprintf(char *, const char *, va_list );
#endif
	...
	...
	...

###############################################################################

The GNU file gstdarg.h which eventaully becomes
	/usr/local/lib/gcc-lib/.../include/stdarg.h
contains the lines

/* stdarg.h for GNU.
   Note that the type used in va_arg is supposed to match the
   actual type **after default promotions**.
   Thus, va_arg (..., short) is not valid.  */

#ifndef _STDARG_H
#define _STDARG_H
	...
	...
	...
#ifdef _HIDDEN_VA_LIST  /* On OSF1, this means varargs.h is "half-loaded".  */
#undef _VA_LIST
#endif

/* The macro _VA_LIST_ is the same thing used by this file in Ultrix.  */
#ifndef _VA_LIST_
/* The macro _VA_LIST is used in SCO Unix 3.2.  */
#ifndef _VA_LIST
#define _VA_LIST_
#define _VA_LIST
#ifndef __svr4__
typedef char *va_list;
#else
typedef void *va_list;
#endif
#endif /* _VA_LIST */
#endif /* _VA_LIST_ */
	...
	...
	...

Since <stdio.h> does not mention _HIDDEN_VA_LIST, a source program that begins
with

#include	<stdio.h>
#include	<stdarg.h>

leaves "va_list" undefined.

The sequence

#include	<stdarg.h>
#include	<stdio.h>

defines "va_list".

If /usr/include/stdarg.h is used explicitly,
	#include	"/usr/include/stdarg.h"
there is no problem in either case.

###############################################################################

The complete program (modified in the #inlcude lines only) that led to this
report is

#ifdef FIRST
#include <stdio.h>
#include "/usr/include/stdarg.h"
#else	/* FIRST */
#include "/usr/include/stdarg.h"
#include <stdio.h>
#endif	/* FIRST */

struct spurious
{
    int anumber;
};

int first(char *fmt, ...)
{
    int pos, number;
    va_list args;
    int dummy;

    va_start(args, fmt);
    for (pos = 0; fmt[pos]; pos++)
	if (fmt[pos] == 'i')
	{
	    number = va_arg(args, int);
	    printf("%d", number);
	}
	else
	    putchar(fmt[pos]);
    va_end(args);
    putchar('\n');
    return dummy;
}

struct spurious second(char *fmt, ...)	/* same as 'first', except for the */
{					/* return type */
    int pos, number;
    va_list args;
    struct spurious dummy;

    va_start(args, fmt);
    for (pos = 0; fmt[pos]; pos++)
	if (fmt[pos] == 'i')
	{
	    number = va_arg(args, int);
	    printf("%d", number);
	}
	else
	    putchar(fmt[pos]);
    va_end(args);
    putchar('\n');
    return dummy;
}

main()
{
    first("hi there this works", 5, 20);
    second("hi there this works", 5, 20); /* no, it doesn't */
}


This program works when FIRST is either defined or not defined on the gcc
command line.


Marv Graham; Convex Computer Corp.  {uunet,sun,uiucdcs,allegra}!convex!graham
					graham@bach.convex.com
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads