Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read
Q&A

Assert that some code is not present in the final binary, at compile or link time.

+3
−0

I'd like to assert that some code can be optimized out, and is not present in the final binary object.

#define CONSTANT  0

#if (!CONSTANT)
[[landmine_A]]
#endif
static int foo(void);

void bar(void)
{
    if (CONSTANT) {
        foo();
    }
}

static int foo(void)
{
    if (!CONSTANT)
        landmine_B();
}

Attributes, builtins, expressions, ..., everything is fair play, as long as it guarantees that the program is not built with foo(), unless #define CONSTANT 1.

I'd like the compiler (or linker, but preferably the compiler) to warn/error if foo() is used, but not if it's inside an if (0).

In the past, this could probably be achieved by __builtin_unreachable();, and the corresponding warning, but it's ignored nowadays...

An option (the one in use, which I'm trying to improve), is to build conditionally foo, but then I also need to use preprocessor stuff at call site, which I don't entirely like, because it hides code to the compiler, so I need to test multiple configurations.

Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

1 answer

+2
−0

Calling an undefined function will have that behavior at link time:

landmine.c:

#ifndef CONSTANT
#define CONSTANT  0
#endif

#define assert_not_in_binary_if(e)  do \
{ \
	if (e) \
		undefined_function(); \
} while (0)

void undefined_function(void);
[[gnu::noipa]] static void foo0(void);
[[gnu::noipa]] static void foo1(void);

int main(void)
{
	CONSTANT ? foo1() : foo0();
}

static void foo0(void)
{
	assert_not_in_binary_if(!CONSTANT);
}

static void foo1(void)
{
	assert_not_in_binary_if(!CONSTANT);
}
alx@asus5775:~/tmp$ cc -Wall -Wextra -O3 -DCONSTANT=1 landmine.c
alx@asus5775:~/tmp$ cc -Wall -Wextra -O3 -DCONSTANT=0 landmine.c
/usr/bin/ld: /tmp/ccmIFcBz.o: in function `foo0':
landmine.c:(.text+0x1): undefined reference to `undefined_function'
collect2: error: ld returned 1 exit status

I used [[gnu::noipa]] just to check which function is triggering the assertion, and it is foo0() as expected, and only when CONSTANT == 0.

It would be nicer to have a compile-time assertion, but link-time is good enough.

EDITED: renamed landmine() to assert_not_in_binary_if(), per Dirk's suggestion.

Why does this post require moderator attention?
You might want to add some details to your flag.

2 comment threads

Why not use static assert? (4 comments)
Nice trick, would suggest different name for readability (2 comments)

Sign up to answer this question »

This community is part of the Codidact network. We have other communities too — take a look!

You can also join us in chat!

Want to advertise this community? Use our templates!

Like what we're doing? Support us! Donate