From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5970 invoked by alias); 11 Aug 2010 17:04:26 -0000 Received: (qmail 4001 invoked by alias); 11 Aug 2010 17:04:12 -0000 Date: Wed, 11 Aug 2010 17:04:00 -0000 Message-ID: <20100811170412.3997.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug c++/45249] Indirect variable parameters sometimes cause segmentation fault In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "rogerio at rilhas dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2010-08/txt/msg00863.txt.bz2 ------- Comment #21 from rogerio at rilhas dot com 2010-08-11 17:04 ------- Subject: Re: Indirect variable parameters sometimes cause segmentation fault Yes, I was using that solution up to 2003, but then I stopped using it in favour of the more confortable &format (the one I showed you) because it is less error-prone and easier to automate (no need for the va_list declaration, start, and end). My teams usually have a lot of rookies (we have schollarship programs) and bugs would popup a lot (like switching the order of parameters, for example). I could go back to using it, of course, but I already have a lot of code done with this &format method, and it is not convenient for me to go back and change anything in old code. Anyway, I seem to have found a workaround for this problem in GCC: it seems that if I use the &format before calling the format_indirect then there will be no problem (still to conform). void format_direct(char* dst_buffer, int dst_buffer_size_bytes, const char* format, ...) { const char** format_address=&format; format_indirect(dst_buffer, dst_buffer_size_bytes, format_address); } If I confirm this then this problem would no longer be blocking and I would be able to live with it by creating a special macro in Linux to use the &format before calling format_indirect: #define GCC_SPECIFIC_ADDRESS_OF(format) const char** format_address(&format) void format_direct(char* dst_buffer, int dst_buffer_size_bytes, const char* format, ...) { format_indirect(dst_buffer, dst_buffer_size_bytes, GCC_SPECIFIC_ADDRESS_OF(format)); } ... or something along these lines. Maybe I should also replace const char** by some other GCC-specificy defined type (that would have no effect on Windows) just to get compilation errors where people try to pass &format directly whitout using the macro. matz at gcc dot gnu dot org wrote: > ------- Comment #20 from matz at gcc dot gnu dot org 2010-08-11 16:10 ------- > A conforming variant of what you probably are trying to code is: > -------------------------------------------------------------------- > #include > #include > > void format_indirect(char* dst_buffer, size_t dst_buffer_size_bytes, > const char *format, va_list va) > { > vsnprintf(dst_buffer, dst_buffer_size_bytes, format, va); > dst_buffer[dst_buffer_size_bytes-1]=0; > } > > void format_direct(char* dst_buffer, size_t dst_buffer_size_bytes, > const char* format, ...) > { > va_list va; > va_start (va, format); > format_indirect(dst_buffer, dst_buffer_size_bytes, format, va); > va_end (va); > } > > int main(void) > { > char buffer[1000]; > format_direct((char*)buffer, sizeof(buffer), "%s %s", __DATE__, __TIME__); > printf("Result: \"%s\"\n", buffer); > return 0; > } > ----------------------------------------------------------- > > Note how the va_list is constructed in the function that actually is > a varargs one, in particular how the necessary parameter is mentioned. > Note further how that va_list is passsed to the function that is not > varargs in order to capture all variable arguments of its caller. > > There, no assumption on stack-layout. It will work with all types and > ABIs, even those that happen to pass even some varargs in registers, > not on the stack. > > > -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45249