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).