[Top][All Lists]
[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.