如何在 OSX 上编译此代码

How compile this code on OSX

考虑这段代码:

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

struct data {
    int nr;
    char const *value;
} dat[] = {
    {1, "Foo"}, {2, "Bar"}, {3, "Hello"}, {4, "World"}
};

int data_cmp(void const *lhs, void const *rhs) 
{
    struct data const *const l = lhs;
    struct data const *const r = rhs;
    return (l->nr > r->nr) - (l->nr < r->nr);
}

int main(void) 
{
    struct data key = { .nr = 3 };
    struct data const *res = bsearch(&key, dat, sizeof(dat)/sizeof(dat[0]), 
                                    sizeof(dat[0]), data_cmp);
    if (!res) {
        printf("No %d not found\n", key.nr);
    } else {
        printf("No %d: %s\n", res->nr, res->value);
    }
}

此版本的 C++ 无法编译代码:

$ g++ -v
Target: x86_64-apple-darwin14.4.0
Thread model: posix

编译成功使用此版本的 g++ 并添加 -fpermissive 选项。

g++ --std=c++11 -fpermissive main.cpp &&./a.out
gcc version 5.2.0 (GCC) 

如果我需要在OSX中编译它,我该怎么办?

这部分代码:

int data_cmp(void const *lhs, void const *rhs) 
{
    struct data const *const l = lhs;
    struct data const *const r = rhs;

不是有效的 C++ 代码。如果没有显式转换,则无法从 const void * 转换为其他任何内容。它是有效的 C 代码,但不是 C++。

要么使用 C 编译器编译,要么修复代码使其成为有效的 C++。

int data_cmp(void const *lhs, void const *rhs) 
{
    struct data const *const l = (struct data *)lhs;
    struct data const *const r = (struct data *)rhs;

bsearch()的结果赋值类似。您也可以使用 reinterpret_cast<const struct data *>(lhs)。因此,编译成功:

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

struct data {
    int nr;
    char const *value;
} dat[] = {
    {1, "Foo"}, {2, "Bar"}, {3, "Hello"}, {4, "World"}
};

int data_cmp(void const *lhs, void const *rhs) 
{
    struct data const *const l = reinterpret_cast<const struct data *>(lhs);
    struct data const *const r = reinterpret_cast<const struct data *>(rhs);
    return (l->nr > r->nr) - (l->nr < r->nr);
}

int main(void) 
{
    struct data key = { .nr = 3 };
    struct data const *res = reinterpret_cast<struct data *>(bsearch(&key, dat, sizeof(dat)/sizeof(dat[0]), 
                                    sizeof(dat[0]), data_cmp));
    if (!res) {
        printf("No %d not found\n", key.nr);
    } else {
        printf("No %d: %s\n", res->nr, res->value);
    }
}

但是,如果您打开足够多的警告,您最终还会被告知 .nr 表示法是 C99 指定的初始化程序,在 C++ 中无效(并且您没有为.value 元素)。

最好将 C 代码编译为 C 代码而不是 C++ 代码。

使用自制的 GCC 5.1.0 和来自 XCode 6.4 的 clang++ 在 Mac OS X 10.4.4 Yosemite 上进行检查。