| Deutsch English Français Italiano |
|
<v6uc4i$1rfr$1@news.muc.de> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!news.mixmin.net!news2.arglkargh.de!news.karotte.org!news.space.net!news.muc.de!.POSTED.news.muc.de!not-for-mail
From: Alan Mackenzie <acm@muc.de>
Newsgroups: comp.lang.c
Subject: Re: Is it possible to generate a compile time error from an inline function?
Date: Sat, 13 Jul 2024 17:05:22 -0000 (UTC)
Organization: muc.de e.V.
Message-ID: <v6uc4i$1rfr$1@news.muc.de>
References: <v6tu04$klr$1@news.muc.de> <v6u5lq$3krbn$1@dont-email.me>
Injection-Date: Sat, 13 Jul 2024 17:05:22 -0000 (UTC)
Injection-Info: news.muc.de; posting-host="news.muc.de:2001:608:1000::2";
logging-data="60923"; mail-complaints-to="news-admin@muc.de"
User-Agent: tin/2.6.3-20231224 ("Banff") (FreeBSD/14.0-RELEASE-p5 (amd64))
Bytes: 4020
Lines: 82
Hello, David.
Many thanks for the reply! It's just what I was looking for.
David Brown <david.brown@hesbynett.no> wrote:
> On 13/07/2024 15:04, Alan Mackenzie wrote:
>> Hello, comp.lang.c.
>>
>> What I want to do is check the validity of (constant) arguments to an
>> inline function, and output a compiler error if they are invalid.
>>
>> In particular, I have:
>>
>> u32 __always_inline ACM_BITFIELD (u8 a[], int offset, int length)
>>
>> , which is to extract a bitfield of LENGTH bits, starting at bit number
>> OFFSET in the array of bytes A. OFFSET and LENGTH will be known at
>> compile time.
>>
>> For the sake of run time efficiency, I wish to impose the restrictions
>> that either (i) the bitfield will be contained entirely within a byte; or
>> (ii) the bitfield will be a number of consecutive whole bytes (maximum 32
>> bits).
>>
>> So, for example, if the code called
>>
>> foo = ACM_BITFIELD (bar, 14, 4);
>>
>> , I would like to output the compiler message "Invalid arguments 14, 4,
>> to ACM_BITFIELD", since this bitfield straddles two bytes.
>>
>> Is there any way I can do this in C? (Before anybody asks, yes I have
>> looked at doing it with macros, but that seems impractical, if it's even
>> possible.)
>>
>> Thanks!
>>
> C does not have a way to force checks for this kind of thing at compile
> time. But if you are using an optimising compiler, you can perhaps rely
> on dead-code elimination along with link-time checks.
> For example, declare a function "compile_time_error()" but do not define
> it anywhere. Then add a check :
> if (length > 8) compile_time_error();
> As long as your check is not too complicated in relation to your
> compiler's optimisation abilities, if it knows the value of "length" at
> compile time it and can see it is no more than 8, the call to
> compile_time_error() will be eliminated. If not, the call will be kept
> and your link will fail as the function does not exist.
This might be the way to go. The number of erroneous calls to
ACM_BITFIELD is expected to be low. The check is just there to make it
difficult for the optimisations in the function to create nonsense. But
if there are ~30 calls to the function, it would then be difficult to
located the erroneous one. So, perhaps ....
> If you are using gcc (or, I expect, clang), you can go further.
> First, define the compile_time_error() function with an error attribute:
> extern void __attribute__((error("Compile time error")))
> compile_time_error(void);
> Then if the call is not eliminated, you will get an error message at
> compile time rather than waiting for link time.
> Add a "__attribute__((always_inline))" attribute to your bitfield
> function - if it is used in a context that is not inlined, that will
> show up as an error.
> You might also find the gcc built-in function __builtin_constant_p(...)
> useful to determine if an expression value is known at compile time, in
> case you want to add run-time checking for complex cases.
Thanks, these are all things I didn't know. I will look them up in the
GCC manual. :-)
--
Alan Mackenzie (Nuremberg, Germany).