[PATCH 01/18] Put function attributes where C2x specifies.

Alejandro Colomar alx.manpages at gmail.com
Thu Jun 2 18:04:55 UTC 2022


GCC is very generous in where  attributes can be placed.
C2x, the first ISO C standard that standardizes attributes, in
order to be less ambiguous, decided to only allow attributes to be
placed in very specific places.  Function attributes go at the
very beginning of a function prototype (it also allows them to go
after the function identifier and just before the parameter list's
opening parenthesis, but that was a bad decission that I expect to
be dropped before the standard is released, and anyway I don't
like it for many reasons, including that it breaks the ability to
grep for functions using a regex).

See the following test that helps understand this:

$ cat inline.c
[[gnu::always_inline]] static inline void a(void);
static [[gnu::always_inline]] inline void b(void);
static inline [[gnu::always_inline]] void c(void);
static inline void [[gnu::always_inline]] d(void);
static inline void e [[gnu::always_inline]] (void);
static inline void f(void)[[gnu::always_inline]];
static inline void g(void);

static inline void a(void) { return; }
static inline void b(void) { return; }
static inline void c(void) { return; }
static inline void d(void) { return; }
static inline void e(void) { return; }
static inline void f(void) { return; }
static inline void g(void) { return; }

$ clang -Wall -Wextra -Werror -std=c2x inline.c -c
inline.c:2:8: error: an attribute list cannot appear here
static [[gnu::always_inline]] inline void b(void);
       ^~~~~~~~~~~~~~~~~~~~~~
inline.c:3:15: error: an attribute list cannot appear here
static inline [[gnu::always_inline]] void c(void);
              ^~~~~~~~~~~~~~~~~~~~~~
inline.c:4:22: error: 'always_inline' attribute cannot be applied to types
static inline void [[gnu::always_inline]] d(void);
                     ^
inline.c:6:29: error: attribute 'always_inline' ignored, because it cannot be applied to a type [-Werror,-Wignored-attributes]
static inline void f(void)[[gnu::always_inline]];
                            ^
4 errors generated.

$ cc -Wall -Wextra -Werror -std=c2x inline.c -c
inline.c:2:1: error: ‘always_inline’ attribute does not apply to types [-Werror=attributes]
    2 | static [[gnu::always_inline]] inline void b(void);
      | ^~~~~~
inline.c:2:31: error: expected identifier or ‘(’ before ‘inline’
    2 | static [[gnu::always_inline]] inline void b(void);
      |                               ^~~~~~
inline.c:3:1: error: ‘always_inline’ attribute does not apply to types [-Werror=attributes]
    3 | static inline [[gnu::always_inline]] void c(void);
      | ^~~~~~
inline.c:3:38: error: expected identifier or ‘(’ before ‘void’
    3 | static inline [[gnu::always_inline]] void c(void);
      |                                      ^~~~
inline.c:4:1: error: ‘always_inline’ attribute does not apply to types [-Werror=attributes]
    4 | static inline void [[gnu::always_inline]] d(void);
      | ^~~~~~
inline.c:6:1: error: ‘always_inline’ attribute does not apply to types [-Werror=attributes]
    6 | static inline void f(void)[[gnu::always_inline]];
      | ^~~~~~
cc1: all warnings being treated as errors
---
 auto/clang                |  4 ++--
 src/nxt_clang.h           |  2 +-
 src/nxt_conf_validation.c |  5 ++---
 src/nxt_malloc.h          | 12 ++++--------
 src/nxt_mem_zone.h        |  9 ++++-----
 src/nxt_mp.h              | 28 +++++++++++-----------------
 src/nxt_sockaddr.h        | 19 ++++++++-----------
 src/nxt_unit.h            |  8 ++++----
 8 files changed, 36 insertions(+), 51 deletions(-)

diff --git a/auto/clang b/auto/clang
index 1a05b5a..3ea5f65 100644
--- a/auto/clang
+++ b/auto/clang
@@ -147,7 +147,7 @@ nxt_feature_incs=
 nxt_feature_libs=
 nxt_feature_test="#include <stdlib.h>
 
-                  void *f(void) __attribute__ ((__malloc__));
+                  __attribute__ ((__malloc__)) void *f(void);
 
                   void *f(void) {
                       return malloc(1);
@@ -183,7 +183,7 @@ nxt_feature_name=NXT_HAVE_GCC_ATTRIBUTE_UNUSED
 nxt_feature_run=
 nxt_feature_incs=
 nxt_feature_libs=
-nxt_feature_test="static void f(void) __attribute__ ((__unused__));
+nxt_feature_test="__attribute__ ((__unused__)) static void f(void);
 
                   static void f(void)
                   {
diff --git a/src/nxt_clang.h b/src/nxt_clang.h
index 9463834..eff3cd5 100644
--- a/src/nxt_clang.h
+++ b/src/nxt_clang.h
@@ -8,7 +8,7 @@
 #define _NXT_CLANG_H_INCLUDED_
 
 
-#define nxt_inline     static inline __attribute__((always_inline))
+#define nxt_inline     __attribute__((always_inline)) static inline
 #define nxt_noinline   __attribute__((noinline))
 #define nxt_cdecl
 
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c
index ee7ebe4..60b9610 100644
--- a/src/nxt_conf_validation.c
+++ b/src/nxt_conf_validation.c
@@ -76,9 +76,8 @@ static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt,
     const char *fmt, ...);
 static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
     nxt_str_t *value);
-nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt,
-    nxt_conf_value_t *value, void *data)
-    NXT_MAYBE_UNUSED;
+NXT_MAYBE_UNUSED nxt_inline nxt_int_t nxt_conf_vldt_unsupported(
+    nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data);
 
 static nxt_int_t nxt_conf_vldt_mtypes(nxt_conf_validation_t *vldt,
     nxt_conf_value_t *value, void *data);
diff --git a/src/nxt_malloc.h b/src/nxt_malloc.h
index fd5493a..fa5a7b7 100644
--- a/src/nxt_malloc.h
+++ b/src/nxt_malloc.h
@@ -8,14 +8,10 @@
 #define _NXT_UNIX_MALLOC_H_INCLUDED_
 
 
-NXT_EXPORT void *nxt_malloc(size_t size)
-    NXT_MALLOC_LIKE;
-NXT_EXPORT void *nxt_zalloc(size_t size)
-    NXT_MALLOC_LIKE;
-NXT_EXPORT void *nxt_realloc(void *p, size_t size)
-    NXT_MALLOC_LIKE;
-NXT_EXPORT void *nxt_memalign(size_t alignment, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_malloc(size_t size);
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_zalloc(size_t size);
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_realloc(void *p, size_t size);
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_memalign(size_t alignment, size_t size);
 
 
 #if (NXT_DEBUG)
diff --git a/src/nxt_mem_zone.h b/src/nxt_mem_zone.h
index 89d73ca..e15ea42 100644
--- a/src/nxt_mem_zone.h
+++ b/src/nxt_mem_zone.h
@@ -17,11 +17,10 @@ NXT_EXPORT nxt_mem_zone_t *nxt_mem_zone_init(u_char *start, size_t zone_size,
 #define nxt_mem_zone_alloc(zone, size)                                        \
     nxt_mem_zone_align((zone), 1, (size))
 
-NXT_EXPORT void *nxt_mem_zone_align(nxt_mem_zone_t *zone, size_t alignment,
-    size_t size)
-    NXT_MALLOC_LIKE;
-NXT_EXPORT void *nxt_mem_zone_zalloc(nxt_mem_zone_t *zone, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mem_zone_align(nxt_mem_zone_t *zone,
+    size_t alignment, size_t size);
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mem_zone_zalloc(nxt_mem_zone_t *zone,
+    size_t size);
 NXT_EXPORT void nxt_mem_zone_free(nxt_mem_zone_t *zone, void *p);
 
 
diff --git a/src/nxt_mp.h b/src/nxt_mp.h
index a5aaabd..a38d3df 100644
--- a/src/nxt_mp.h
+++ b/src/nxt_mp.h
@@ -31,9 +31,8 @@ typedef struct nxt_mp_s  nxt_mp_t;
  * nxt_mp_create() creates a memory pool and sets the pool's retention
  * counter to 1.
  */
-NXT_EXPORT nxt_mp_t *nxt_mp_create(size_t cluster_size, size_t page_alignment,
-    size_t page_size, size_t min_chunk_size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE nxt_mp_t *nxt_mp_create(size_t cluster_size,
+    size_t page_alignment, size_t page_size, size_t min_chunk_size);
 
 /*
  * nxt_mp_destroy() destroys memory pool in spite of the pool's retention
@@ -64,46 +63,41 @@ NXT_EXPORT nxt_bool_t nxt_mp_is_empty(nxt_mp_t *mp);
  * nxt_mp_alloc() returns aligned freeable memory.
  * The alignment is sutiable to allocate structures.
  */
-NXT_EXPORT void *nxt_mp_alloc(nxt_mp_t *mp, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mp_alloc(nxt_mp_t *mp, size_t size);
 
 
 /*
  * nxt_mp_zalloc() returns zeroed aligned freeable memory.
  * The alignment is sutiable to allocate structures.
  */
-NXT_EXPORT void *nxt_mp_zalloc(nxt_mp_t *mp, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mp_zalloc(nxt_mp_t *mp, size_t size);
 
 /* nxt_mp_align() returns aligned freeable memory. */
-NXT_EXPORT void *nxt_mp_align(nxt_mp_t *mp, size_t alignment, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mp_align(nxt_mp_t *mp, size_t alignment,
+    size_t size);
 
 /* nxt_mp_zalign() returns zeroed aligned freeable memory. */
-NXT_EXPORT void *nxt_mp_zalign(nxt_mp_t *mp, size_t alignment, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mp_zalign(nxt_mp_t *mp, size_t alignment,
+    size_t size);
 
 /* nxt_mp_free() frees freeable memory. */
 NXT_EXPORT void nxt_mp_free(nxt_mp_t *mp, void *p);
 
 
 /* nxt_mp_nget() returns non-aligned non-freeable memory. */
-NXT_EXPORT void *nxt_mp_nget(nxt_mp_t *mp, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mp_nget(nxt_mp_t *mp, size_t size);
 
 /*
  * nxt_mp_get() returns aligned non-freeable memory.
  * The alignment is sutiable to allocate structures.
  */
-NXT_EXPORT void *nxt_mp_get(nxt_mp_t *mp, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mp_get(nxt_mp_t *mp, size_t size);
 
 /*
  * nxt_mp_zget() returns zeroed aligned non-freeable memory.
  * The alignment is sutiable to allocate structures.
  */
-NXT_EXPORT void *nxt_mp_zget(nxt_mp_t *mp, size_t size)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE void *nxt_mp_zget(nxt_mp_t *mp, size_t size);
 
 
 NXT_EXPORT nxt_int_t nxt_mp_cleanup(nxt_mp_t *mp, nxt_work_handler_t handler,
diff --git a/src/nxt_sockaddr.h b/src/nxt_sockaddr.h
index a8f1b39..4da193b 100644
--- a/src/nxt_sockaddr.h
+++ b/src/nxt_sockaddr.h
@@ -71,17 +71,14 @@ nxt_sockaddr_t *nxt_sockaddr_cache_alloc(nxt_event_engine_t *engine,
     nxt_listen_socket_t *ls);
 void nxt_sockaddr_cache_free(nxt_event_engine_t *engine, nxt_conn_t *c);
 
-NXT_EXPORT nxt_sockaddr_t *nxt_sockaddr_alloc(nxt_mp_t *mp, socklen_t socklen,
-    size_t address_length)
-    NXT_MALLOC_LIKE;
-NXT_EXPORT nxt_sockaddr_t *nxt_sockaddr_create(nxt_mp_t *mp,
-    struct sockaddr *sockaddr, socklen_t socklen, size_t address_length)
-    NXT_MALLOC_LIKE;
-NXT_EXPORT nxt_sockaddr_t *nxt_sockaddr_copy(nxt_mp_t *mp, nxt_sockaddr_t *src)
-    NXT_MALLOC_LIKE;
-NXT_EXPORT nxt_sockaddr_t *nxt_getsockname(nxt_task_t *task, nxt_mp_t *mp,
-    nxt_socket_t s)
-    NXT_MALLOC_LIKE;
+NXT_EXPORT NXT_MALLOC_LIKE nxt_sockaddr_t *nxt_sockaddr_alloc(nxt_mp_t *mp,
+    socklen_t socklen, size_t address_length);
+NXT_EXPORT NXT_MALLOC_LIKE nxt_sockaddr_t *nxt_sockaddr_create(nxt_mp_t *mp,
+    struct sockaddr *sockaddr, socklen_t socklen, size_t address_length);
+NXT_EXPORT NXT_MALLOC_LIKE nxt_sockaddr_t *nxt_sockaddr_copy(nxt_mp_t *mp,
+    nxt_sockaddr_t *src);
+NXT_EXPORT NXT_MALLOC_LIKE nxt_sockaddr_t *nxt_getsockname(nxt_task_t *task,
+    nxt_mp_t *mp, nxt_socket_t s);
 NXT_EXPORT void nxt_sockaddr_text(nxt_sockaddr_t *sa);
 
 
diff --git a/src/nxt_unit.h b/src/nxt_unit.h
index 35f9fa5..4826d66 100644
--- a/src/nxt_unit.h
+++ b/src/nxt_unit.h
@@ -355,11 +355,11 @@ void nxt_unit_free(nxt_unit_ctx_t *ctx, void *p);
 #endif
 
 
-void nxt_unit_log(nxt_unit_ctx_t *ctx, int level, const char* fmt, ...)
-    NXT_ATTR_FORMAT;
+NXT_ATTR_FORMAT void nxt_unit_log(nxt_unit_ctx_t *ctx, int level,
+    const char* fmt, ...);
 
-void nxt_unit_req_log(nxt_unit_request_info_t *req, int level,
-    const char* fmt, ...) NXT_ATTR_FORMAT;
+NXT_ATTR_FORMAT void nxt_unit_req_log(nxt_unit_request_info_t *req, int level,
+    const char* fmt, ...);
 
 #if (NXT_DEBUG)
 
-- 
2.36.1



More information about the unit mailing list