Can an ANSI C-compliant implementation include additional functions in its standard library?
Asked Answered
C

2

11

Is an ANSI C-compliant implementation allowed to include additional types and functions in its standard library, beyond those enumerated by the standard? (An ideal answer would reference the relevant part of the ANSI standard.)

I ask particularly because Mac OS 10.7 declares the getline function in stdio.h, even when compiling with gcc or clang using the -ansi flag. This breaks several older programs that define their own getline function. Is this a fault of Mac OS 10.7? (The man page for getline on Mac OS 10.7 says that getline conforms to the POSIX.1 standard, which came in 2008.)

Edit: To clarify, I find it odd that including stdio.h in an ANSI C89 program on Mac OS 10.7 also pulls in the declaration for the getline function, since getline is not one of the functions enumerated in the K&R (and presumably ANSI) description of stdio.h. In particular, attempting to compile noweb:

gcc -ansi -pedantic    -c -o notangle.o notangle.c
In file included from notangle.nw:28:
getline.h:4: error: conflicting types for ‘getline’
/usr/include/stdio.h:449: error: previous declaration of ‘getline’ was here

Is it a bug in Mac OS 10.7 includes the declaration of getline in stdio.h even when compiling for the ANSI C89 standard?

Coreen answered 11/9, 2011 at 5:53 Comment(0)
O
15

From section 7.1.3 paragraph 2 of n1570 (which is a draft of C1x):

No other identifiers are reserved.

This is the part that means getline shouldn't be defined by the <stdio.h>, since it's not a reserved identifier according to the spec. So if your library defines getline in <stdio.h>, it's not technically compliant with the C standard...

However, you should be able to use the feature test macros to cause getline to be undefined in <stdio.h>.

#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>

This will give you only the definitions from the older POSIX standards. This won't work on some GNU C++ implementations, which is ExTrEmeLY fruSTRaTiNG for some folks.

The relevant section of the manpage is (taken from a glibc manpage, sorry...)

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       getline(), getdelim():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
           Before glibc 2.10:
               _GNU_SOURCE

This part of the manpage tells you which macros need to be defined to which values in order to get the definition. My bet is that _POSIX_C_SOURCE is already defined by your compiler to 200809L.

The idea of feature test macros is that if you define your macros, like _POSIX_C_SOURCE, _BSD_SOURCE, _XOPEN_SOURCE, etc. to the values you want, you won't need to worry about new library functions clashing with your existing functions. There is also _GNU_SOURCE, which turns everything on if you use glibc, but I suggest giving that macro a wide berth.

Omnifarious answered 11/9, 2011 at 6:16 Comment(2)
Your answer has allowed me to get the ANSI C89 code compiling again, via defining _POSIX_C_SOURCE 1. (This value is supposed to enable only the ANSI C89/ISO C90 features.) These feature test macros are not documented in the Mac man page for getline, and the feature_test_macros man page doesn't exist on the Mac. I wouldn't have found them without your answer. Although your answer now doesn't answer my original question (is an ANSI C implementation allowed to declare other functions in its standard library), your answer addresses my actual problem. I would upvote twice if I could!Coreen
The part of the standard that says "No other identifiers are reserved" means that the implementation is not technically allowed to define other functions in its headers, but I wasn't exactly clear about that.Omnifarious
C
4

Yes, a compliant implementation is allowed to define additional identifiers, including functions, as long as they are one of the reserved identifiers in the standard. For example:

  • All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use;

  • All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces;

  • All external names that begin with is, to, str, mem or wcs followed by a lowercase letter;

In addition there are names that are reserved only if you include certain headers; for example, if you include <errno.h> then it can define any macro starting with E followed by a digit or uppercase letter.

However, getline() is not such a reserved name, and a compliant implementation must make it available for the programmer's own use.

Clinkscales answered 11/9, 2011 at 9:50 Comment(2)
This is almost the answer I am looking for. Do you have a reference that justifies your claim that getline() must be available for the programmer's own use?Coreen
@Bradford Larsen: The C standard (N1256 is the final C99 standard as updated by TC1, TC2 and TC3). In particular see sections 7.1.3 and 7.26.Clinkscales

© 2022 - 2024 — McMap. All rights reserved.