3

I have worked on several projects in college on C, but never used it in professional capacity.

Recently I started reading through cpython's source code and the following syntax confused me: github

What does PyAPI_FUNC(int) PyToken_OneChar(int); the part before the function name mean? Is it a wrapper function that dynamically constructs the return type?

I am not even sure what to Google search for, in this case!

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
Aditya
  • 1,240
  • 2
  • 14
  • 38
  • 2
    Looks like a macro to me. Peek through the other include files and see if you can find a `#define` anywhere for it. – Charles Srstka Oct 02 '18 at 00:29
  • 3
    When I do a Google search for '`pyapi_func`', I get a collection of useful looking links, such as '[Python-Dev — What do PyAPI_FUNC & PyAPI_DATA mean?](https://mail.python.org/pipermail/python-dev/2012-April/118987.html) — part of an email thread about `PyAPI_FUNC`. Basically, you do a search on the term that confuses and see what happens. In this case, because the name is anything but generic, it turns up useful data. If you had a macro LIST in the code, then your search would be much harder. But trying a simple search is easy. – Jonathan Leffler Oct 02 '18 at 00:48

2 Answers2

6

PyAPI_FUNC() is a macro defined in pyport.h. The particular definition depends on the platform you're building on, but here's an example:

#define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE

So the line in your question, PyAPI_FUNC(int) PyToken_OneChar(int); expands to:

__declspec(dllimport) int PyToken_OneChar(int);

Basically, it just declares the name PyToken_OneChar as a function that takes an int as its parameter and returns an int, but it does it in a way that lets the compiler embed storage information with those types. See What is __declspec and when do I need to use it? for more information about the __declspec directive if you're interested. Another of the definitions for PyAPI_FUNC is:

#define PyAPI_FUNC(RTYPE) RTYPE

which skips all that and just expands the line above to:

int PyToken_OneChar(int);

So the main thing to take away from this is that source code that's meant to compile on multiple platforms often uses macros that make it easier to write code once and use it on each of those platforms. In this case, it lets the programmers write declarations for PyToken_OneChar() and many other functions once instead of having to write (and maintain!) different versions for each platform. This is fairly advanced stuff -- not something you should worry about if you're getting started.

Caleb
  • 124,013
  • 19
  • 183
  • 272
4

It's a C Macro they wrote which allows them to do different things on different OS platforms, for instance, on windows, this will export the function as part of the public interface for a DLL.

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156