From tim@mysql.com  Mon Dec  4 23:40:21 2006
Return-Path: <tim@mysql.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id F2B1E16A416
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  4 Dec 2006 23:40:21 +0000 (UTC)
	(envelope-from tim@mysql.com)
Received: from mailgate.mysql.com (mailgate-out2.mysql.com [213.136.52.68])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 0E4A043CEC
	for <FreeBSD-gnats-submit@freebsd.org>; Mon,  4 Dec 2006 23:37:31 +0000 (GMT)
	(envelope-from tim@mysql.com)
Received: from localhost (localhost.localdomain [127.0.0.1])
	by mailgate.mysql.com (8.13.4/8.13.4) with ESMTP id kB4Nc6ZU018957
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 5 Dec 2006 00:38:06 +0100
Received: from mail.mysql.com ([10.222.1.99])
 by localhost (mailgate.mysql.com [10.222.1.98]) (amavisd-new, port 10026)
 with LMTP id 17178-03 for <FreeBSD-gnats-submit@freebsd.org>;
 Tue,  5 Dec 2006 00:38:05 +0100 (CET)
Received: from siva.hindu.god (10-100-64-38.mysql.internal [10.100.64.38])
	(authenticated bits=0)
	by mail.mysql.com (8.13.3/8.13.3) with ESMTP id kB4Nbv4p027731
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 5 Dec 2006 00:38:02 +0100
Received: by siva.hindu.god (Postfix, from userid 1001)
	id C92995C78; Mon,  4 Dec 2006 16:37:57 -0700 (MST)
Message-Id: <20061204233757.C92995C78@siva.hindu.god>
Date: Mon,  4 Dec 2006 16:37:57 -0700 (MST)
From: Timothy Smith <trangayesi@gmail.com>
Reply-To: Timothy Smith <trangayesi@gmail.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: macros in stdio.h non-portable (e.g., C++ ::feof() fails)
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         106355
>Category:       bin
>Synopsis:       [headers] macros in stdio.h non-portable (e.g., C++ ::feof() fails)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    jilles
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 04 23:50:06 GMT 2006
>Closed-Date:    Sun Apr 06 11:27:44 UTC 2014
>Last-Modified:  Sun Apr 06 11:27:44 UTC 2014
>Originator:     Timothy Smith
>Release:        FreeBSD 6.1-STABLE i386
>Organization:
>Environment:
System: FreeBSD siva.hindu.god 6.1-STABLE FreeBSD 6.1-STABLE #0: Sun Jun 18 13:23:52 MDT 2006 root@siva.hindu.god:/usr/obj/usr/src/sys/GENERIC i386


	
>Description:
FreeBSD's /usr/include/stdio.h defines a number of macros, such as
feof(), fileno(), etc.  These are not mentioned in manual pages, and I
can't find any reference in POSIX or C standards which allow it.

It causes code like the following C++ program to be non-portable.  It
compiles fine on Solaris, Linux, Windows, OS X.  It does fail on HPUX
as well, by the way, so FreeBSD isn't alone in using this technique.
Perhaps it is allowed by the standard, and the code is non-conformant.

<cstdio> does #undef most of these macros.  But checking c++ -E -dM
output after #include <cstdio> shows that at least fileno() is still
defined as a macro that won't allow ::fileno() to succeed:

#define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p))
>How-To-Repeat:
cat > fileno.cpp <<EOF
#include <stdio.h>
int main() { return ::feof(stdout); }
EOF
c++ -g -O -W -Wall fileno.cpp
c++ -E -dD fileno.cpp | tail
c++ -E -dM | grep -v '^#define _'

>Fix:
The workaround is obvious.  Just don't qualify functions from the
standard library as belonging to a namespace.  This doesn't work if a
class defines feof(), for example, and you need to call the global
feof() from inside it.  But arguably that's not a smart thing to do in
the first place.

The other workaround is also obvious:
#ifdef feof
#undef feof
#endif


It would be nice if standard library functions, included from
<stdio.h>, <stdlib.h>, etc., could be explicitly qualified with the
scope operator in C++ code.  A test for __cplusplus might do the
trick, perhaps something like:

#if __cplusplus
/* Hmmm, is this a problem for 6-character-unique symbol names? */
inline int __cpp_feof(FILE *p) {
	return !__isthreaded ? __sfeof(p) : (feof)(p);
}
#define feof(p) __cpp_feof(p)
#else
#define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p))
#endif /* __cplusplus */

Probably something similar could be done for other functions.


It might be a good idea to #undef fileno in cstdio as well.

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: jilles 
State-Changed-When: Sun Apr 6 11:26:01 UTC 2014 
State-Changed-Why:  
As part of the xlocale work 2-3 years ago, the macros were removed for C++ 
compilation. This happened in stable/9 and newer. 


Responsible-Changed-From-To: freebsd-bugs->jilles 
Responsible-Changed-By: jilles 
Responsible-Changed-When: Sun Apr 6 11:26:01 UTC 2014 
Responsible-Changed-Why:  
Track replies. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=106355 
>Unformatted:
