Howdy Ralph,

On 11/10/22 10:31, Ralph Corderoy wrote:
> Howdy Alejandro,
> 

[...]

>>> My patch just changes
>>>      #define length(s)   (sizeof(s) - 1)
>>> to:
>>>      #define length(s)   (nitems(s) - 1)
>>>
>>> (nitems() is defined to be the obvious sizeof division (called
>>> ARRAY_SIZE(9) in the Linux kernel)
> 
> The bug is the original macro str_set() doesn't document its ‘text’
> parameter must be a string constant.  Macros I have to hand are more
> explicit: ‘string constant s’.
> 
>     /* DIM gives the number of elements in the one-dimensional array a. */
>     #define DIM(a) (sizeof (a) / sizeof (*(a)))
> 
>     /* LEN gives the strlen() of string constant s, excluding the
>      * terminating NUL. */
>     #define LEN(s) (sizeof (s) - 1)
> 

[...]

> 
> Unless the value needs to be known at compile time, using strlen(3)
> would work in all cases, save much human time at the cost of a little
> accumulated machine time, and in the simple common case of a string
> constant it will probably be evaluated by any optimising compiler into a
> constant.

I remembered this email series as I was writing some patch set for
shadow, and indeed I faced the issue of strlen(3) not being constexpr
(one of the few things I like from C++, although I haven't used it
extensively, and don't know if I'd still like it after knowing all
it's hidden corners, is constexpr functions).

So I had to write STRLEN(s) as a macro that is NITEMS(s) - 1, which
is both constexpr and safe against pointers.  :)

<https://github.com/shadow-maint/shadow/pull/681>

Cheers,

Alex


-- 
<http://www.alejandro-colomar.es/>
GPG key fingerprint: A9348594CE31283A826FBDD8D57633D441E25BB5

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

Reply via email to