3

次のプログラムをコンパイルすると(C++ の 64 ビット ntohl() から取得したすべての定義のコード?これは賢明に思えました):

#include <stdint.h>
#if defined(__linux__)
#include <endian.h> //htobe64,be64toh
#include <arpa/inet.h> //ntohs, ntohl, htonl, htons
#elif defined(__FreeBSD__) || defined(__NetBSD__)
#include <sys/endian.h>
#elif defined(__OpenBSD__)
#include <sys/types.h>
#define be16toh(x) betoh16(x)
#define be32toh(x) betoh32(x)
#define be64toh(x) betoh64(x)
#endif

int main()
{
    int64_t i = 0x1212121234343434;
    int64_t j = be64toh(i);
    return 0;
}

次のコマンドでコンパイルすると、リンク エラーが発生します (Linux を実行しています)。

gcc -std=c99 endian_test.c -o endian

私が受け取るエラーは次のとおりです。

user@host ~/src/c $ gcc -std=c99 derp.c 
endian_test.c: In function ‘main’:
endian_test.c:17:2: warning: implicit declaration of function ‘be64toh’ [-Wimplicit-function-declaration]
  int64_t j = be64toh(i);
  ^
/tmp/ccYonfH4.o: In function `main':
endian_test.c:(.text+0x23): undefined reference to `be64toh'
collect2: error: ld returned 1 exit status

ヘッダー自体は含まれていますが、これが機能するために必要な関数/マクロが実際には含まれていません.リンクすること。

しかし、次のコマンドを使用してコンパイルすると (削除するだけです-std=c99):

gcc endian_test.c -o endian

すべてがバターのように滑らかで機能します。なぜそれが起こっているのか、それを修正するために何ができるのか考えていますか? コンパイル時に使用する標準に応じて、カーネルによって提供される関数が変わることは意味がありません (または、その事実で間違っていますか?)。

前もって感謝します!

4

4 に答える 4

4

明示的な-std=オプションがない場合、呼び出しはC89 + GNU 拡張を意味するgcc場合と同じです。-std=gnu89GNU 拡張機能は、ヘッダー内の関数の存在を有効にするマクロを有効にします。

于 2013-10-22T18:19:38.393 に答える
3

be64tohマニュアルを見ると、 を定義する必要があることがわかります_BSD_SOURCE。したがって、Linux では#define、含める前に<endian.h>.

于 2013-10-22T18:20:48.607 に答える
1

この問題がありました。解決策は、宣言するだけでなく

#define _BSD_SOURCE 

だけでなく、

#define __USE_BSD

https://github.com/tailhook/zerogw/pull/34/files#r32008569

于 2015-06-09T12:50:55.950 に答える
1

glibc への最近の変更により、次のことが必要になりました

#define _DEFAULT_SOURCE

それ以外の

#define _BSD_SOURCE

_BSD_SOURCE および _SVID_SOURCE 機能マクロの非推奨

于 2015-08-12T07:08:51.650 に答える