Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connections
Warning: mysqli::query(): Couldn't fetch mysqli in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\index.php on line 66
Article <fb9c29d418c137a633f136a36a128ea57532adad@i2pn2.org>
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.