检查编译器是否支持源中的可选C功能

发布于 2025-02-13 02:54:36 字数 529 浏览 0 评论 0原文

我有一个简单的程序(一个非常简单的Malloc/免费实施,最初是为大学作业编写的),该程序必须检查免费指示器的“有效性”,我需要将其取消。为了避免用户提供BS指针时,我想检查内存当前是否映射到我的地址空间中。

我想用

char* pointer_to_memory;

free(void *ptr) {
    if((uintptr_t)ptr < (uintptr_t)pointer_to_memory) {
        abort();
    }
}

现在这样的事情来做到这一点,问题是,C11将UINTPTR_T作为可选功能,这意味着并非所有编译器支持。 我真的不需要代码,因此,我愿意与不支持某种预处理魔法支持UIntptr_t的编译器进行编译时,只愿意将其排除在外。 我知道,指向整数演员的指针并不总是像人们期望的那样工作(例如,指示中似乎还有一些其他信息),但似乎比(直接)指针比较的定义更好。 我也不能仅仅忽略Sigsegv,因为我想忠于大学任务,而且我们不允许使用信号处理程序(我怀疑Sigsegv的播放器不是您应该覆盖的东西,因为

I have a simple program (a VERY simplistic malloc/free implementation, originally written for a university assignment), which has to check the "validity" of the pointers in the free, for which I need to dereference it. To avoid Segfaults when a user supplies a bs pointer, I want to check if the memory is currently mapped into my Addressspace.

I wanted to do this with something like

char* pointer_to_memory;

free(void *ptr) {
    if((uintptr_t)ptr < (uintptr_t)pointer_to_memory) {
        abort();
    }
}

Now, the problem is, that c11 has uintptr_t as an optional feature, meaning not all compiler support that.
I don't really NEED the code, so I would be willing to just leave it out when compiling with a compiler that doesn't support uintptr_t with some kind of preprocessor magic.
I know, that pointer to integer casts are not always working like one would expect them to (ARM seems to have some additional info in the pointers for Example) but it seemed better defined than (direct) pointer comparisons.
I also can't just ignore the SIGSEGV, since I want to stay true to the university assignment and we were not allowed to use Signal Handlers (and I suspect a SIGSEGV hander is not something you should overwrite as a free)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

咿呀咿呀哟 2025-02-20 02:54:36

我愿意与不支持某种预处理魔术的编译器一起编译时将其排除在外。


n。 1.8e9-在哪里,我可以使用
,您可以使用uintptr_max

char* pointer_to_memory;

free(void *ptr)
{
    #if defined(UINTPTR_MAX)
    if((uintptr_t)ptr < (uintptr_t)pointer_to_memory) {
        abort();
    }
    #endif
    // ...
}

为了避免使用BS指针时,我想检查内存是否已映射到我的地址空间中。

您不能迫使用户在C中编写“正确”程序。如果C通过设计允许某人射击脚,那么您将永远无法通过编程来阻止它们。

I would be willing to just leave it out when compiling with a compiler that doesn't support uintptr_t with some kind of preprocessor magic.

As pointed out by
n. 1.8e9-where's-my-share m
, you can use UINTPTR_MAX:

char* pointer_to_memory;

free(void *ptr)
{
    #if defined(UINTPTR_MAX)
    if((uintptr_t)ptr < (uintptr_t)pointer_to_memory) {
        abort();
    }
    #endif
    // ...
}

To avoid Segfaults when a user supplies a bs pointer, I want to check if the memory is currently mapped into my Addressspace.

You cannot force the user to write "correct" programs in C. If C, by design, allows somebody to shoot themselves in the foot, you will never be able stop them programatically.

素年丶 2025-02-20 02:54:36

您可以通过两种方式检测可选功能。

其中之一是检查预处理器宏。 如果(如果是强大的话),则您的编译器遵循标准,您可以期望设置一些预处理器宏,具体取决于水平。对于uintptr_t,即uintptr_max来自stdint.h file。

一些编译器不遵循标准。例如,编译器可以为您提供uintptr_t而无需uintptr_max

第二件事是编译使用该功能的示例程序,请记住编译是否已取消,然后在编译代码时设置自定义预处理器宏或其他操作。这是构建系统的工作方式。 AutoTools具有ac_compile_ifelse,CMAKE具有try_compile检查程序的编译。然后根据汇编的结果,在程序中设置预处理器宏,或者在自动工具的情况下,您将生成不同的config.h文件。

// CMakeLists.txt
string(APPEND CMAKE_REQUIRED_INCLUDES "stdint.h" "limits.h")
include(CheckTypeSize)
check_type_size("uintptr_t" UINTPTR)
if(HAVE_UINTPTR)
   target_compile_definition(yourlib  PREFIX_HAS_UINTPTR)
endif()


// your C code
   #ifdef PREFIX_HAS_UINTPTR
   // use uintptr_t
   #endif

There are two ways you can detect optional features.

One of them is checking a preprocessor macro. If (and that's is a strong if) your compiler is following a standard, you can expect some preprocessor macro to be set depending on the faeture. For uintptr_t that would be UINTPTR_MAX from stdint.h file.

Some compilers do not follow a standard. For example, a compiler may give you uintptr_t without UINTPTR_MAX.

The second thing is to compile an example program that uses the feature, remember if the compilation suceeded, and then set a custom preprocessor macro or different action when compiling your code. This is the way build systems work. Autotools has AC_COMPILE_IFELSE, CMake has try_compile to check a compilation of a program. Then depending on the result of compilation, set a preprocessor macro in your program, or in case of autotools, you would generate a different config.h file.

// CMakeLists.txt
string(APPEND CMAKE_REQUIRED_INCLUDES "stdint.h" "limits.h")
include(CheckTypeSize)
check_type_size("uintptr_t" UINTPTR)
if(HAVE_UINTPTR)
   target_compile_definition(yourlib  PREFIX_HAS_UINTPTR)
endif()


// your C code
   #ifdef PREFIX_HAS_UINTPTR
   // use uintptr_t
   #endif
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文