On Thu, 23 Feb 2012, James K. Lowden wrote:
#ifdef __GNUC__ #define _BSD_VA_LIST_ __builtin_va_list /* GCC built-in type */ #else #define _BSD_VA_LIST_ char * /* XXXfvdl should be ok? */ #endifThat code doesn't depend on x86. It depends on GNU. All I need is another C compiler for x86, and my va_list is magically char* again.
That's a bug, because it means that compiling the caller with one compiler and the callee with another compiler, will give results that don't work (assuming an ABI in which __buitin_va_list is not really compatible with char *). Both compilers should implement the same ABI.
Imagine an architecture with no stack [...] Correctly you will say it is advantageous to use the registers to best advantage, and that stdargs should facilitate that. I agree. Does that mean va_list cannot be a char*? It does not. There is no necessity for stdarg to emulate the register-use convention implemented by the compiler. All that is required is that caller and callee share an understanding of how it is to be used.
Yes. However, you are talking here about what an implementation is allowed to do. As long as all the different parts of the implementation (the compiler, the library, the header files, the linker) are consistent with each other, the implementation is certainly free to use a char* pointer to realise a va_list. Elsewhere, we were talking about what a program is allowed to do, and a program is not free to assume anything about how the implementation handles va_list.
The standard is drawn to give the library-writer latitude. OK, but the library writer is equally free to use that latitude to give the application-writer latitude. It is possible, IOW, to have a standard-compliant library whose documented behavior permits uses not discussed by C99.
Yes, indeed. Following on from my previous paragraph, if the implementation documents it, and the program chooses to step outside the limits of the C standard, then the program can reply on extra guarantees made by the implementation.
2. Nothing about machine architecture mandates anything about the implementation of stdargs.1. The C standard is silent on the subject, as it should be. POSIX likewise defines *minimum* functionality. Nothing prevents a more liberal, useful implementation.
Yes, true again. But once a decision is made, changing it usually involves changing the ABI. Changing the ABI usually means that code compiled under the old ABI won't interoperate with code compiled under the new ABI. I don't think NetBSD is likely to do that.
NetBSD should be a platform to use, not a standards nanny. It shouldn't be the eye of a needle through which code must pass on its way to ... well, to where, exactly? Isn't this exactly a case for allowing stupid things to permit clever ones?
Perhaps a va_list_to_sequential_memory() conversion interface could be provided. It would take a va_list, copy it into the sort of memory buffer that you have advocated, and return a pointer to it, and a size. Or it could skip the copying if the va_list is already in that sort of format. There would probably also have to be a way of freeing the memory.
--apb (Alan Barrett)