0

For the sake of public record, I'm asking here at SE rather than on the standardization mailing list, so that it'd be more accessible to people.

With practically every headers that specify functions (or function-like interfaces), there's the following:

The following shall be declared as functions and may also be defined as macros. Function prototypes shall be provided.

It's troubling me because it has the potential implication that some functions that I use may not be assignable to function pointers as they may have been defined as macros.

However, the second part ("prototypes shall be provided") seems to suggest, that, if those said functions are named differently from what the standard says, then that different name must have a identical prototype (or at least one compatible in every enumerable aspect) to that specified in the standard.

Is my interpretation correct? If not, what's the real interpretation? Can I assign the listed interfaces below that paragraph to function pointers?

2
  • 1
    What standard are you talk about? Whose headers? Commented Aug 8, 2022 at 13:45
  • @MiniMax This is clearly (if you're familiar with the topic) about the C programming language. Commented Aug 8, 2022 at 17:49

1 Answer 1

3

The following shall be declared as functions and may also be defined as macros.

doesn’t imply that functions can no longer be referenced if they have also been defined as macros.

Consider isalnum, which is commonly a macro:

#include <ctype.h>
#include <stdio.h>

int main(int argc, char **argv) {
  printf("%p\n", isalnum);
  printf("%d\n", isalnum('C'));
}

In present-day C, the first isalnum reference can’t be a macro: when isalnum is a macro, it’s declared as isalnum(c) or equivalent, so a parameter-less reference doesn’t match. The second reference can be either a macro or a function (and you can see which by passing the code through your preprocessor); if you want to ensure the latter, you can #undef as appropriate, or use parentheses ((isalnum)('C')).

The actual requirement behind that statement in the C standard is that the functions introduced in this way must always be available as actual functions, even if they are (also) defined as macros.

Function prototypes shall be provided.

Prototypes are a different concern; the requirement there is that, rather than a simple

extern int isalnum();

declaration, the header files provide complete prototypes with type information for all the arguments.

See Defining C functions in the C Standard Library as macros for references.

if those said functions are named differently from what the standard says

Functions with a different name than that specified in the standard are of no concern to the standard (as long as they satisfy the general requirements of the standard).

2
  • Is #undef isalnum actually permitted in C? AFAIR the standard library may #define isalnum __isalnum, which makes isalnum completely indistinguishable from __isalnum as long as you aren't using the preprocessor, but means that if you undefine the standard name, it's no available at all. Commented Aug 8, 2022 at 17:52
  • 2
    @Gilles C11 section 7.1.4 says “The use of #undef to remove any macro definition will also ensure that an actual function is referred to.” Only function-like macros are allowed to replace functions, so #define isalnum __isalnum isn’t valid (in current versions of the standard). The standard requires that isalnum itself exist as a function, so relying on something like __isalnum only isn’t valid either. Commented Aug 8, 2022 at 17:56

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.