Deutsch   English   Français   Italiano  
<v6u5lq$3krbn$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: David Brown <david.brown@hesbynett.no>
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:15:06 +0200
Organization: A noiseless patient Spider
Lines: 67
Message-ID: <v6u5lq$3krbn$1@dont-email.me>
References: <v6tu04$klr$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:15:06 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="dae6d3308ea626ceac54b1e213f1a152";
	logging-data="3829111"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1+uHxpwwPhsNbOT3Ww8Lp7fKgvATfX0L6I="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:PeiPR7huf7kid8G3VkrQVF59mc8=
Content-Language: en-GB
In-Reply-To: <v6tu04$klr$1@news.muc.de>
Bytes: 3595

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.


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.