[master] bbfbaeb6b vdef: add vcountof() macro
Nils Goroll
nils.goroll at uplex.de
Mon Jul 21 13:23:05 UTC 2025
commit bbfbaeb6ba85465f5f8ab6c3e8674470ad944b3a
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Fri Jul 11 11:40:54 2025 +0200
vdef: add vcountof() macro
add vcountof() as an almost-standard replacement for sizeof(array) /
sizeof(*array) in its various forms
diff --git a/bin/varnishd/acceptor/cache_acceptor_tcp.c b/bin/varnishd/acceptor/cache_acceptor_tcp.c
index 8efac3694..56fb84f30 100644
--- a/bin/varnishd/acceptor/cache_acceptor_tcp.c
+++ b/bin/varnishd/acceptor/cache_acceptor_tcp.c
@@ -77,7 +77,7 @@ static struct sock_opt sock_opts[] = {
#undef SOCK_OPT
};
-static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0];
+static const int n_sock_opts = vcountof(sock_opts);
/*--------------------------------------------------------------------
* We want to get out of any kind of trouble-hit TCP connections as fast
diff --git a/bin/varnishd/acceptor/cache_acceptor_uds.c b/bin/varnishd/acceptor/cache_acceptor_uds.c
index d67f552a5..7387b8d5c 100644
--- a/bin/varnishd/acceptor/cache_acceptor_uds.c
+++ b/bin/varnishd/acceptor/cache_acceptor_uds.c
@@ -83,7 +83,7 @@ static struct sock_opt sock_opts[] = {
#undef SOCK_OPT
};
-static const int n_sock_opts = sizeof sock_opts / sizeof sock_opts[0];
+static const int n_sock_opts = vcountof(sock_opts);
/*--------------------------------------------------------------------
* Some kernels have bugs/limitations with respect to which options are
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 1ebc27005..7b19df12c 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -250,7 +250,7 @@ static struct hsh_magiclist {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
};
-#define HSH_NMAGIC (sizeof hsh_magiclist / sizeof hsh_magiclist[0])
+#define HSH_NMAGIC vcountof(hsh_magiclist)
static void
hsh_testmagic(void *result)
diff --git a/bin/varnishd/hpack/vhp_gen_hufdec.c b/bin/varnishd/hpack/vhp_gen_hufdec.c
index 121e897d0..d6252c59d 100644
--- a/bin/varnishd/hpack/vhp_gen_hufdec.c
+++ b/bin/varnishd/hpack/vhp_gen_hufdec.c
@@ -53,7 +53,7 @@ static const struct {
#include "tbl/vhp_huffman.h"
};
-#define HUF_LEN (sizeof huf / sizeof huf[0])
+#define HUF_LEN vcountof(huf)
struct tbl;
diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index 254275ebd..6e9e5bdc9 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -104,7 +104,7 @@ static const h2_error stream_errors[] = {
#undef H2EC3
};
-#define NSTREAMERRORS (sizeof(stream_errors)/sizeof(stream_errors[0]))
+#define NSTREAMERRORS vcountof(stream_errors)
static h2_error
h2_streamerror(uint32_t u)
@@ -130,7 +130,7 @@ static const h2_error conn_errors[] = {
#undef H2EC3
};
-#define NCONNERRORS (sizeof(conn_errors)/sizeof(conn_errors[0]))
+#define NCONNERRORS vcountof(conn_errors)
static h2_error
h2_connectionerror(uint32_t u)
@@ -504,7 +504,7 @@ static const struct h2_setting_s * const h2_setting_tbl[] = {
#include <tbl/h2_settings.h>
};
-#define H2_SETTING_TBL_LEN (sizeof(h2_setting_tbl)/sizeof(h2_setting_tbl[0]))
+#define H2_SETTING_TBL_LEN vcountof(h2_setting_tbl)
static void
h2_win_adjust(const struct h2_sess *h2, uint32_t oldval, uint32_t newval)
@@ -1486,7 +1486,7 @@ static const h2_frame h2flist[] = {
#include "tbl/h2_frames.h"
};
-#define H2FMAX (sizeof(h2flist) / sizeof(h2flist[0]))
+#define H2FMAX vcountof(h2flist)
int
h2_rxframe(struct worker *wrk, struct h2_sess *h2)
diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c
index f49bb358d..07894bcd0 100644
--- a/bin/varnishd/mgt/mgt_cli.c
+++ b/bin/varnishd/mgt/mgt_cli.c
@@ -64,7 +64,7 @@ static const struct cli_cmd_desc *cmds[] = {
#include "tbl/cli_cmds.h"
};
-static const int ncmds = sizeof cmds / sizeof cmds[0];
+static const int ncmds = vcountof(cmds);
static int cli_i = -1, cli_o = -1;
struct VCLS *mgt_cls;
diff --git a/include/vdef.h b/include/vdef.h
index 5c5b5325a..9a88323e3 100644
--- a/include/vdef.h
+++ b/include/vdef.h
@@ -213,6 +213,14 @@ int __llvm_gcov_flush(void);
#define vlimit(a, l, u) vmax((l), vmin((a), (u)))
#define vlimit_t(type, a, l, u) vmax_t(type, (l), vmin_t(type, (a), (u)))
+/**********************************************************************
+ * Number of elements in an array
+ *
+ * Data on bikeshedding:
+ * https://thephd.dev/the-big-array-size-survey-for-c-results
+ */
+#define vcountof(arr) ((sizeof(arr) / sizeof((arr)[0])))
+
/**********************************************************************
* FlexeLint and compiler shutuppery
*/
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index bb9ac5a03..29c6e0808 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -132,7 +132,7 @@ static const struct VSC_level_desc levels[] = {
#include "tbl/vsc_levels.h"
};
-static const ssize_t nlevels = sizeof(levels)/sizeof(*levels);
+static const ssize_t nlevels = vcountof(levels);
/*--------------------------------------------------------------------*/
diff --git a/tools/coccinelle/vcountof.cocci b/tools/coccinelle/vcountof.cocci
new file mode 100644
index 000000000..277c27908
--- /dev/null
+++ b/tools/coccinelle/vcountof.cocci
@@ -0,0 +1,35 @@
+// Use the macro vcountof when possible
+//
+// Confidence: High
+// Copyright: (C) Gilles Muller, Julia Lawall, EMN, INRIA, DIKU. GPLv2.
+// URL: https://coccinelle.gitlabpages.inria.fr/website/rules/array.html
+// Options: -I ... -all_includes can give more complete results
+//
+// copied and modified from https://coccinelle.gitlabpages.inria.fr/website/rules/array.cocci
+
+using "varnish.iso"
+
+@@
+type T;
+T[] E;
+@@
+
+- (sizeof(E)/sizeof(*E))
++ vcountof(E)
+
+@@
+type T;
+T[] E;
+@@
+
+- (sizeof(E)/sizeof(E[...]))
++ vcountof(E)
+
+@@
+type T;
+T[] E;
+@@
+
+- (sizeof(E)/sizeof(T))
++ vcountof(E)
+
More information about the varnish-commit
mailing list