具有以下编译器标志:

-std=c11 -Werror -Wpedantic

Oracle Solaris14.6要求为clock_gettime()的声明定义_POSIX_C_SOURCE/_XOPEN_SOURCE,我将此testing library包含在下面的翻译单元中.

该代码在定义后可以正常编译,但在Apple MacOS下编译时会失败,并出现以下错误:

cc -std=c11 -fPIC -Wall -Wextra -Werror -Wwrite-strings -Wno-unused-variable -Wno-parentheses -Wpedantic -Warray-bounds -Wno-unused-function -Wstrict-prototypes -Wdeprecated -DDEBUG    tests.c   -o tests
In file included from tests.c:19:
In file included from ./acutest.h:377:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/sysctl.h:83:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/ucred.h:101:2: error: unknown type name 'u_int'
        u_int   cr_version;             /* structure layout version */
        ^
In file included from tests.c:19:
In file included from ./acutest.h:377:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/sysctl.h:85:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/proc.h:116:2: error: unknown type name 'u_int'
        u_int   p_estcpu;        /* Time averaged value of p_cpticks. */
        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/proc.h:121:2: error: unknown type name 'u_int'
        u_int   p_swtime;        /* Time swapped in or out. */
        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/proc.h:122:2: error: unknown type name 'u_int'
        u_int   p_slptime;       /* Time since last blocked. */
        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/proc.h:136:2: error: unknown type name 'u_char'; did you mean 'char'?
        u_char  p_priority;     /* Process priority. */
        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/proc.h:137:2: error: unknown type name 'u_char'; did you mean 'char'?
        u_char  p_usrpri;       /* User-priority based on p_cpu and p_nice. */
        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/proc.h:142:2: error: unknown type name 'u_short'; did you mean 'short'?
        u_short p_xstat;        /* Exit status for wait; also stop signal. */
        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/proc.h:143:2: error: unknown type name 'u_short'; did you mean 'short'?
        u_short p_acflag;       /* Accounting flags. */
        ^
8 errors generated.
make[1]: *** [tests] Error 1
make: *** [test] Error 2
Error: Process completed with exit code 2.

这些未知类型是什么?为什么如果我删除宏,这些错误就会消失?

目前,我通过仅定义_POSIX_C_SOURCE/_XOPEN_SOURCE来避免这些:

#if defined(__sun) && defined(__SVR4)
    #define _POSIX_C_SOURCE 200819L
    #define _XOPEN_SOURCE 700
#endif

这是翻译单元:

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
    #define HAVE_STDALIGN_H
    #include <stdalign.h>
#endif

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>


#define _POSIX_C_SOURCE 200819L
#define _XOPEN_SOURCE 700

#include "acutest.h"

#include "arena.c"

/* *INDENT-OFF* */
/* In C2X/C23 or later, nullptr is a keyword. */
/* Patch up C18 (__STDC_VERSION__ == 201710L) and earlier versions.  */
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ <= 201710L
    #define nullptr ((void *)0)
#endif
/* *INDENT-ON* */

static inline bool is_aligned(const void *ptr, size_t byte_count)
{
    return (uintptr_t) ptr % byte_count == 0;
}

static void test_arena_new(void)
{
    TEST_CHECK(arena_new(stderr, 0) == nullptr);

    Arena *const arena = arena_new(nullptr, 100);

    TEST_CHECK(arena);
    arena_destroy(arena);

    uint8_t *const backing_storage1 = malloc(100 * (size_t) 1024);

    TEST_ASSERT(backing_storage1);

    Arena *const heap_arena = arena_new(backing_storage1, 100 * (size_t) 1024);

    TEST_CHECK(heap_arena);
    arena_destroy(heap_arena);
    free(backing_storage1);

#ifdef HAVE_STDALIGN_H
    static uint8_t alignas (max_align_t) backing_storage2[BUFSIZ];
    Arena *const static_arena =
        arena_new(backing_storage2, sizeof backing_storage2);
    TEST_CHECK(static_arena);
    arena_destroy(static_arena);

    uint8_t alignas (max_align_t) backing_storage3[BUFSIZ];
    Arena *const thread_local_arena =
        arena_new(backing_storage3, sizeof backing_storage3);
    TEST_CHECK(thread_local_arena);
    arena_destroy(thread_local_arena);
#endif
}

static void test_arena_destroy(void)
{
    Arena *const arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);
    arena_destroy(arena);
}

static void test_arena_reset(void)
{
    Arena *const arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);
    arena_reset(arena);

    for (size_t i = 0; i < arena->count; ++i) {
        TEST_CHECK(arena->pools[i]->offset == 0);
    }

    TEST_CHECK(arena->current == 1);
    arena_destroy(arena);
}

static void test_arena_alloc(void)
{
    Arena *const arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);

    TEST_CHECK(arena_alloc(arena, 1, 112) == nullptr);
    TEST_CHECK(arena_alloc(arena, 0, 1) == nullptr);
    TEST_CHECK(arena_alloc(arena, 1, 0) == nullptr);
    TEST_CHECK(arena_alloc(arena, 2, 5) == nullptr);
    TEST_CHECK(arena_alloc(arena, 3, 5) == nullptr);

    TEST_CHECK(arena_alloc(arena, 1, 95));
    uint8_t *const curr_pool = arena->pools[0]->buf;

    TEST_CHECK(curr_pool[96] == 0xA5 && curr_pool[97] == 0xA5
        && curr_pool[98] == 0xA5 && curr_pool[99] == 0xA5);

    arena_reset(arena);

#ifdef HAVE_STDALIGN_H
    const int *const a = arena_alloc(arena, alignof (int), 5 * sizeof *a);
    const double *const b = arena_alloc(arena, alignof (double), 2 * sizeof *b);
    const char *const c = arena_alloc(arena, 1, 10);
    const short *const d = arena_alloc(arena, alignof (short), 5 * sizeof *d);

    TEST_CHECK(a && is_aligned(a, alignof (int)));
    TEST_CHECK(b && is_aligned(b, alignof (double)));
    TEST_CHECK(c && is_aligned(c, 1));
    TEST_CHECK(d && is_aligned(d, alignof (short)));
#endif
    arena_destroy(arena);
}

static void test_arena_resize(void)
{
    Arena *arena = arena_new(nullptr, 1000);

    TEST_ASSERT(arena);

    TEST_CHECK(arena_resize(arena, stderr, 0) == nullptr);

    arena = arena_resize(arena, nullptr, 10000);
    TEST_CHECK(arena);
    TEST_CHECK(arena->current == 2 && arena->count == 2);

    const char *c = arena_alloc(arena, 1, 10000);

    TEST_ASSERT(c);

    arena_reset(arena);
    TEST_CHECK(arena->current == 1 && arena->count == 2);
    arena_destroy(arena);
}

static void test_arena_allocarray(void)
{
    Arena *const arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);

#ifdef HAVE_STDALIGN_H
    const int *const nums =
        arena_allocarray(arena, alignof (int), 10, sizeof *nums);
    TEST_CHECK(nums);
#endif

    TEST_CHECK(arena_allocarray(arena, 0, 10, 20) == nullptr);
    TEST_CHECK(arena_allocarray(arena, 10, 0, 20) == nullptr);
    TEST_CHECK(arena_allocarray(arena, 10, 20, 0) == nullptr);
    TEST_CHECK(arena_allocarray(arena, 2, 10, SIZE_MAX) == nullptr);

    arena_destroy(arena);
}

static void test_arena_realloc(void)
{
    Arena *const arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);

    TEST_ASSERT(arena_alloc(arena, 1, 10));
    TEST_CHECK(arena->pools[0]->offset == 10 && arena->last_alloc_size == 10);

    /* Test expansion. */
    TEST_CHECK(arena_realloc(arena, 20));
    TEST_CHECK(arena->pools[0]->offset == 20 && arena->last_alloc_size == 20);

    /* Test shrinking. */
    TEST_CHECK(arena_realloc(arena, 15));
    TEST_CHECK(arena->pools[0]->offset == 15 && arena->last_alloc_size == 15);

    /* Test deletion. */
    TEST_CHECK(arena_realloc(arena, 0));
    TEST_CHECK(arena->pools[0]->offset == 0 && arena->last_alloc_size == 0);
    arena_destroy(arena);
}

static void test_arena_pool_capacity(void)
{
    Arena *const arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);
    TEST_ASSERT(arena_alloc(arena, 1, 40));
    TEST_CHECK(arena_pool_capacity(arena) == 60);

    TEST_ASSERT(arena_alloc(arena, 1, 49));
    TEST_CHECK(arena_pool_capacity(arena) == 11);

    TEST_ASSERT(arena_alloc(arena, 1, 11));
    TEST_CHECK(arena_pool_capacity(arena) == 0);
    arena_destroy(arena);
}

static void test_arena_allocated_bytes(void)
{
    Arena *arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);
    arena = arena_resize(arena, nullptr, 10002);
    TEST_ASSERT(arena);
    TEST_CHECK(arena_allocated_bytes(arena) == 10102);
    arena_destroy(arena);
}

static void test_arena_allocated_bytes_including_metadata(void)
{
    Arena *arena = arena_new(nullptr, 100);

    TEST_ASSERT(arena);
    arena = arena_resize(arena, nullptr, 10002);
    TEST_CHECK(arena_allocated_bytes_including_metadata(arena) == 10102
        + offsetof(Arena, pools)
        + sizeof arena->pools[0] * arena->capacity);
    arena_destroy(arena);
}

/* *INDENT-OFF* */
TEST_LIST = {
    { "arena_new", test_arena_new },
    { "arena_destroy", test_arena_destroy },
    { "arena_reset", test_arena_reset },
    { "arena_alloc", test_arena_alloc },
    { "arena_resize", test_arena_resize },
    { "arena_allocarray", test_arena_allocarray },
    { "arena_realloc", test_arena_realloc },
    { "arena_pool_capacity", test_arena_pool_capacity},
    { "arena_allocated_bytes", test_arena_allocated_bytes },
    { "arena_allocated_bytes_including_metadata", test_arena_allocated_bytes_including_metadata },
    { nullptr, nullptr }
};
/* *INDENT-ON* */

推荐答案

在任何其他includedefine指令修复缺失类型的所有错误之前,将<sys/types.h>包含在tests.c中.正如@Eric在 comments 中所说,这不是纠正,只是目前的一个笨拙.

C++相关问答推荐

如何从C中的公钥字符串创建EVP_PKEY

如何将一个enum类型类型转换为另一个类型?

理解C中的指针定义

函数指针始终为零,但在解除引用和调用时有效

sizeof结果是否依赖于字符串的声明?

返回一个包含数组的 struct

C/SDL程序,渲染不使用我的渲染器

我编译了一个新的c程序,并收到以下错误

如何使用低级C++写出数值

如何跨平台处理UTF-16字符串?

如何捕捉只有换行符或空格字符缓冲区的边缘大小写

C-使用指针返回修改后的整数数组

S在本文中的价值观到底出了什么问题?

如何仅使用软件重新初始化STM32微控制器中的USB枚举?

这段代码用于在C中以相反的顺序打印数组,但它不起作用

哪个首选包含第三个库S头文件?#INCLUDE;文件名或#INCLUDE<;文件名&>?

在文件描述符上设置FD_CLOEXEC与将其传递给POSIX_SPOWN_FILE_ACTIONS_ADCLOSE有区别吗?

`%%的sscanf无法按预期工作

GDB 跳过动态加载器代码

在 C/C++ 中原子按位与字节的最佳方法?