lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] dealing with standard C functions implemented as macros


From: Greg Chicares
Subject: Re: [lmi] dealing with standard C functions implemented as macros
Date: Mon, 24 Mar 2008 16:24:58 +0000
User-agent: Thunderbird 2.0.0.12 (Windows/20080213)

On 2008-03-23 20:45Z, Vadim Zeitlin wrote:
> 
>  I'd like to know if there is an official policy for using standard
> functions which can be implemented as macros.

C++1998, 17.4.1.2/6 says:

"Names that are defined as functions in C shall be defined as
functions in the C++ Standard Library."

and its footnote 159 says:

"This disallows the practice, allowed in C, of providing a
'masking macro' in addition to the function prototype."

and Table 94 in 27.8.2/1 says ferror() is a function, not a
macro.

> The case in point is the use
> of ferror() in md5.cpp which does
> 
>       if (n == 0 && std::ferror (stream))
> 
> The problem is that when ferror() is a macro, this doesn't compile (FYI
> the expansion of std::ferror(stream) in my particular case becomes
> "std::((stream)->_flag & _IOERR)" which is syntactically invalid).

AFAICT, msvc is wrong in this case.

BTW, a dinkumware C++ conformance test for FreeBSD said:

http://groups.google.com/group/lucky.freebsd.standards/msg/b31809713b19ffcf
| The following list covers the faults uncovered while testing
| compliance
...
| The functions feof, ferror, clearerr, getc, putc, getchar, and
| putchar in stdio.h are defined as macros.

but this all seems quite odd because AFAIK dinkumware provides
the C++ library that msvc uses, and they would certainly have
run their own conformance testsuite. Yet I guess they wouldn't
overrule their biggest customer's preferences.

>  I see 2 possible solutions:
> 
> 1. Do an "#undef ferror" to force the use of a function version. I'm not
>    100% sure if an implementation is allowed to define ferror() solely as
>    a macro but I don't think, even though I can't find the exact reference
>    right now I believe that the function version must be always provided.
>    But if there is any uncertainty about this we could, of course, use this
>    #undef for MSVC only which is known to provide both macro and function
>    versions of ferror().

Sounds like a good approach to me. I'd prefer something like:

'config_msvc.hpp' [a new file, like 'config_bc551.hpp']
...
#include <cstdio>
// [Explanation of the compiler defect]
#undef ferror

Writing "#undef ferror" in every source file that uses ferror()
would be ugly and error prone. I'm willing to include <cstdio>
implicitly in every file (with msvc only) if that's the price of
quarantining a compiler defect cleanly.

> 2. Remove "std::" and include stdio.h instead of cstdio header.

I don't like to change correct code to accommodate an incorrect
compiler. I did that often in the past for borland, and came to
regret it.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]