После повторной реализации некоторых функций libc (в «личном» проекте моей школьной библиотеки под названием libft
), у меня возникла идея реализовать некоторые из них в виде макросов, например:
#define ft_isalnum(c) (ft_isalpha(c) || ft_isdigit(c))
#define ft_isalpha(c) (ft_isupper(c) || ft_islower(c))
#define ft_isascii(c) (((c) >= 0) && ((c) <= 0177))
#define ft_isdigit(c) (((c) >= '0') && ((c) <= '9'))
#define ft_islower(c) (((c) >= 'a') && ((c) <= 'z'))
#define ft_isprint(c) (((c) >= 0040) && ((c) <= 0176))
#define ft_isspace(c) ((((c) >= 0x09) && ((c) <= 0x0d)) || ((c) == 0x20))
#define ft_isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
Однако вскоре я обнаружил, что такие инструкции, как ft_isspace(s[--len])
, становятся не работает, потому что переменная len
трижды декрементируется. Поэтому мне пришлось создавать настоящие функции вместо макросов.
Я знаю, что макросы небезопасны. Но я вижу, что реализации GNU/BSD libc тестов is*(3)
символов являются макросами. Как они защищают свои макросы?
Мне не разрешено (в школе) использовать функции, которые я не реализовал сам (кроме malloc(3)
, free(3)
и нескольких системных вызовов, таких как write(2)
. И я предполагаю, что вызов функции только для проверки символа ASCII довольно неэффективен.
Спасибо.