4

そのため、私たちが使用するベンダーは、次のことを行うライブラリ (主に C 用で、一部の C++ をサポート) を提供しています。

#ifndef int64_t
#define int64_t s_int64
#endif
#ifndef int32_t
#define int32_t s_int32
#endif
#ifndef int16_t
#define int16_t s_int16
#endif
#ifndef int8_t
#define int8_t  s_int8
#endif

ライブラリの奥深くにあるヘッダーの1つ。問題は、ライブラリが次のような単純な C++11 コードに含まれていることです。

#include <iostream>

#include <vendor/library.h>

int main(void)
{
  std::int32_t std_i = 0;
  return std_i;
}

すぐにコンパイラ エラー ( s_int32is not in std::) が発生します。質問は、ベンダーにこの修正をしつこく要求する以外に、私たちのコードでこれを回避する方法はありますか? (ところで、ヘッダーの#include <cstdint> に私が試したこと、運がない、extern "C"ラッパー、運がない。ヘッダーがインストールされて/usr/include/いるので、インクルードの順序を制御できない...)

4

4 に答える 4

21

それらの定義は未定義にすることができます。

#undef int64_t
#undef int32_t
#undef int16_t
#undef int8_t
于 2013-10-15T09:30:49.253 に答える
5

プリプロセッサには巧妙な特性があります: マクロの置換中の再帰が防止されます! したがって、次のように定義できます。

#define int64_t int64_t
#define int32_t int32_t
#define int16_t int16_t
#define int8_t int8_t

ベンダーのヘッダーを含める前。そうすれば、( を使用して#ifndefいるため) 再定義されることはなく、コードの残りの部分で意図した意味を保持します。

于 2013-10-15T09:47:01.673 に答える
4

ファイル内に他に何があるかを確認せずに、100% 機能するソリューションを見つけるのは困難です。

ただし、試すことができる1つのアイデアは次のとおりです(注-これは私のコンパイラで漠然と試しましたが、他のコンパイラで動作することは保証しません)。

それらの定義を含むファイルを作成しますが、typedef として作成します。

typedef s_int64 int64_t;
...

次に、一部のコンパイラでは、コマンドラインで他のファイルよりも前に含めるファイルを指定できます...たとえば、gccには-includeスイッチがあるため、このファイルを含めるように指定します。

次に、コマンドラインでも、自分自身にマップする定義を作成できます。

-Dint64_t=int64_t

または、定義を上記のファイルに入れます。

#define int64_t int64_t

その結果、理論的には、#defines他のコードに干渉することはありません (何もするべきではありません - 再帰的な展開になってしまう可能性があるかどうかはわかりません)。typedefを正しい型に作成したので、ベンダーのコードは引き続き機能するはずです。

強制的にインクルードされるファイルに typedef を配置する理由は、それが何よりも先にインクルードされるようにするためです。

次に、ベンダーにコードを更新してtypedef. あなたは顧客であり、彼らはあなたに製品を売りたいと思っています。

すべての理論的な心。

于 2013-10-15T09:47:40.440 に答える
0

彼らは#ifndefマクロを使用しています。つまり、定義されていない場合、値は...

最初に値で定義するだけです:

#define int64_t (xx)
#define int32_t (xx)
#define int16_t (xx)
#define int8_t  (xx)
于 2013-10-15T09:32:14.570 に答える