Enhance Py_ARRAY_LENGTH(): fail at build time if the argument is not an array

Move other various macros to pymcacro.h

Thanks Rusty Russell for having written these amazing C macros!
This commit is contained in:
Victor Stinner 2011-09-29 01:12:24 +02:00
parent 2bdc7f591b
commit dfb866d127
5 changed files with 65 additions and 19 deletions

View File

@ -48,6 +48,7 @@
#include <assert.h>
#include "pyport.h"
#include "pymacro.h"
#include "pyatomic.h"
@ -126,24 +127,6 @@
#include "pystrcmp.h"
#include "dtoa.h"
#include "fileutils.h"
/* Argument must be a char or an int in [-128, 127] or [0, 255]. */
#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff))
#include "pyfpe.h"
/* Define macros for inline documentation. */
#define PyDoc_VAR(name) static char name[]
#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
#ifdef WITH_DOC_STRINGS
#define PyDoc_STR(str) str
#else
#define PyDoc_STR(str) ""
#endif
#define Py_ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0]))
#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif /* !Py_PYTHON_H */

57
Include/pymacro.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef Py_PYMACRO_H
#define Py_PYMACRO_H
#define Py_MIN(x, y) (((x) > (y)) ? (y) : (x))
#define Py_MAX(x, y) (((x) > (y)) ? (x) : (y))
/* Argument must be a char or an int in [-128, 127] or [0, 255]. */
#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff))
/* Assert a build-time dependency, as an expression.
Your compile will fail if the condition isn't true, or can't be evaluated
by the compiler. This can be used in an expression: its value is 0.
Example:
#define foo_to_char(foo) \
((char *)(foo) \
+ Py_BUILD_ASSERT(offsetof(struct foo, string) == 0))
Written by Rusty Russell, public domain. */
#define Py_BUILD_ASSERT(cond) \
(sizeof(char [1 - 2*!(cond)]) - 1)
#if defined(__GNUC__)
/* Two gcc extensions.
&a[0] degrades to a pointer: a different type from an array */
#define _Py_ARRAY_LENGTH_CHECK(array) \
Py_BUILD_ASSERT(!__builtin_types_compatible_p(typeof(array), \
typeof(&(array)[0])))
#else
#define _Py_ARRAY_LENGTH_CHECK(array) 0
#endif
/* Get the number of elements in a visible array
This does not work on pointers, or arrays declared as [], or function
parameters. With correct compiler support, such usage will cause a build
error (see Py_BUILD_ASSERT).
Written by Rusty Russell, public domain. */
#define Py_ARRAY_LENGTH(array) \
(sizeof(array) / sizeof((array)[0]) + _Py_ARRAY_LENGTH_CHECK(array))
/* Define macros for inline documentation. */
#define PyDoc_VAR(name) static char name[]
#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
#ifdef WITH_DOC_STRINGS
#define PyDoc_STR(str) str
#else
#define PyDoc_STR(str) ""
#endif
#endif /* Py_PYMACRO_H */

View File

@ -718,6 +718,7 @@ PYTHON_HEADERS= \
Include/pyfpe.h \
Include/pymath.h \
Include/pygetopt.h \
Include/pymacro.h \
Include/pymem.h \
Include/pyport.h \
Include/pystate.h \

View File

@ -825,6 +825,7 @@ Rauli Ruohonen
Jeff Rush
Sam Rushing
Mark Russell
Rusty Russell
Nick Russo
Patrick Sabin
Sébastien Sablé

View File

@ -886,6 +886,10 @@
RelativePath="..\Include\pytime.h"
>
</File>
<File
RelativePath="..\Include\pymacro.h"
>
</File>
<File
RelativePath="..\Include\pymem.h"
>