| Deutsch English Français Italiano |
|
<fb9c29d418c137a633f136a36a128ea57532adad@i2pn2.org> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!weretis.net!feeder9.news.weretis.net!i2pn.org!i2pn2.org!.POSTED!not-for-mail
From: Richard Damon <richard@damon-family.org>
Newsgroups: comp.lang.c
Subject: Re: Is it possible to generate a compile time error from an inline
function?
Date: Sat, 13 Jul 2024 13:34:35 -0400
Organization: i2pn2 (i2pn.org)
Message-ID: <fb9c29d418c137a633f136a36a128ea57532adad@i2pn2.org>
References: <v6tu04$klr$1@news.muc.de> <v6u5lq$3krbn$1@dont-email.me>
<v6uc4i$1rfr$1@news.muc.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 13 Jul 2024 17:34:35 -0000 (UTC)
Injection-Info: i2pn2.org;
logging-data="3137774"; mail-complaints-to="usenet@i2pn2.org";
posting-account="diqKR1lalukngNWEqoq9/uFtbkm5U+w3w6FQ0yesrXg";
User-Agent: Mozilla Thunderbird
X-Spam-Checker-Version: SpamAssassin 4.0.0
In-Reply-To: <v6uc4i$1rfr$1@news.muc.de>
Content-Language: en-US
Bytes: 4599
Lines: 86
On 7/13/24 1:05 PM, Alan Mackenzie wrote:
> 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. :-)
>
In C++, I would use constexpr and static_assert to do this, and your
compiler might allow its use in C as an extension.
If not, in C you could use just _Static_assert, perhaps in the expansion
of a macro that generates the expression that does the testing.