Sunday, May 10, 2015

Digest for comp.lang.c++@googlegroups.com - 13 updates in 3 topics

Marcel Mueller <news.5.maazl@spamgourmet.org>: May 10 09:18AM +0200

On 09.05.15 13.24, Öö Tiib wrote:
 
> Most probably (about 95% of time) the defect is where the call is made
> to function with ellipsis parameter and where the programmer-entered list
> does not match with programmer-entered format.
 
gcc checks for that with a reasonable hit rate.
Furthermore using a static buffer fixes the problem for him. This
wouldn't fix and parameter type issues.
 
> of format with C standard library functions that have ellipsis parameter.
 
> Messing with 'va_list' and 'char const*' format does not let compilers
> to do that.
 
There is a pragma for gcc to enforce that whereever ... is used this
way. (And I never used ... for anything else.)
 
> So even if the code is correct ... my impression is
> that ... just avoid doing it. ;)
 
Well, this is the old discussion about printf. Without using external
libraries (and dependencies) there is no reasonable alternative for
error message handling. Adding an additional library based on variadic
templates is likely to cause more problems than printf format strings.
If the messages code does not fit within one line the code becomes
unreadable. And invoking a stringstream each time is really annoying.
 
> Especially when neither of you nor that
> "someone else" is capable of taking and debugging actual standard library
> code and seeing what really goes wrong there.
 
He tries to dig it. It seems that invoking vsnprintf twice with the same
va raises the problem.
 
 
Marcel
"Öö Tiib" <ootiib@hot.ee>: May 10 01:44AM -0700

On Sunday, 10 May 2015 10:18:26 UTC+3, Marcel Mueller wrote:
 
> gcc checks for that with a reasonable hit rate.
> Furthermore using a static buffer fixes the problem for him. This
> wouldn't fix and parameter type issues.
 
Is the issue caused by calling vsnprintf twice or caused by usage
of '&str[0]' for buffer?
 
> > to do that.
 
> There is a pragma for gcc to enforce that whereever ... is used this
> way. (And I never used ... for anything else.)
 
I didn't know of such pragma existing. What pragma it is?

> templates is likely to cause more problems than printf format strings.
> If the messages code does not fit within one line the code becomes
> unreadable. And invoking a stringstream each time is really annoying.
 
The library that uses variadic templates is usually couple of header
files ... but indeed, anything can cause problems.
 
> > code and seeing what really goes wrong there.
 
> He tries to dig it. It seems that invoking vsnprintf twice with the same
> va raises the problem.
 
So something of the 'int count = vsnprintf(NULL, 0, format, va);' corrupts
'va' for next call? If he uses fixed buffer in next call (that ignores
the 'count') then does he get garbage in fixed buffer as well?
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>: May 10 11:07AM +0200


> He tries to dig it. It seems that invoking vsnprintf twice with the
> same va raises the problem.
 
You can't reuse an instance of va_list. This is fairly clear in the
manpage (on Linux). Sorry, I'm lazy to look it up in the standards.
 
| The va_arg() macro expands to an expression that has the type and value
| of the next argument in the call. The argument ap is the va_list ap
| initialized by va_start(). Each call to va_arg() modifies ap so that
| the next call returns the next argument. [...]
|
| If ap is passed to a function that uses va_arg(ap,type) then the value
| of ap is undefined after the return of that function.
 
So in the code you gave earlier:
 
> ret.resize(count);
> return ret;
> }
 
the first call to vsnprint kills "va" (by repeatedly calling va_arg),
and the second call to vsnprintf gets garbage. You need to use va_copy()
to be conform, even on systems where it seems to work.
 
-- Alain.
Marcel Mueller <news.5.maazl@spamgourmet.org>: May 10 11:23AM +0200

On 10.05.15 10.44, Öö Tiib wrote:
>> wouldn't fix and parameter type issues.
 
> Is the issue caused by calling vsnprintf twice or caused by usage
> of '&str[0]' for buffer?
 
It is not fully proven, but it seems that the first one is the problem.
 
>> There is a pragma for gcc to enforce that whereever ... is used this
>> way. (And I never used ... for anything else.)
 
> I didn't know of such pragma existing. What pragma it is?
 
#ifdef __GNUC__
#define PRINTFATTR(i) __attribute__((format(printf, i, i+1)))
#else
#define PRINTFATTR(i)

No comments: