2013-04-11 19 views
5

g ++バージョン3.somethingでうれしくコンパイルされたコードがあります。私はそれから、g ++ 4.7にアップグレードしたので、C++ 11のシンボルを持つ他のコードをビルドしたかったのです。今私の元のコードは構築されません。エラー "'fdopen'が宣言されていませんでしたg ++ 3でコンパイルされたg ++ 4で見つかりました

が「fdopenを」(fdopenをmanページによると、このスコープ

で宣言されていなかった)私は含めていstdio.hで宣言されている:私はエラーを取得します。私はそれが適切であるかどうかはわかりませんが、私はCygwin環境で作業しています。 g ++の正確なバージョンは、Cygwinが提供するバージョン4.7.2です。

私はコンパイラを切り替えてからこのコードを変更していないので、それがビルドされ、テストコードが実行され、以前のコンパイラに渡されたことを確かめることができます。

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

int main(int argc, char **argv) 
{ 
    int fd; 
    FILE *fp; 

    fd = open("test.txt", (O_WRONLY | O_CREAT | O_EXCL), S_IRWXU); 
    if(0 < fd) 
    { 
     fp = fdopen(fd, "wb"); 

     fprintf(fp, "Testing...\n"); 
     fclose(fp); 
    } 

    return 0; 
} 


# g++ -std=c++11 -o test test.cpp 
test.cpp: In function 'int main(int, char**)': 
test.cpp:14:29: error: 'fdopen' was not declared in this scope 
+0

いくつかのコードを見ることなく、確かに知るのは難しいですが、まだ助けとなる問題を示している小さなサンプルに凝縮することができます。 –

+0

コードが追加されました。私は最初から書きました。私の謝罪、問題の説明から、必要に応じて上記のコードが仮定できると思いました。基本的にfdopenはマニュアルページに従ってに宣言されており、g ++ 3でコンパイルするとその関数が見つかり、g ++ 4ではありません。だから、ちょうどfdopen()をいくつかのコードに入れてコンパイルすると、同じ問題が発生します。 – AlastairG

答えて

3

問題が-std=c++11から来ている:

としては、問題を示すために、サンプルコードを要求しました。 fdopen()関数はANSI C(POSIX標準のみ)にはありません。-std=c++11オプションでコンパイルすると、からいくつかの関数を除いた__STRICT_ANSI__が定義されています。ちなみに、C++プログラムでは、<stdio.h>の代わりに<cstdio>を含める必要があります。stdio.h not standard in C++?を参照してください。

fdopen()を使用する必要がある場合は、コンパイル時に-std=c++11オプションを削除することをお勧めします。別の可能soltionは、本当にエレガントされていないが、あなたのソースコードでこれを使用することができます。

-std=c++11オプションでとせずに動作するように意図された)
#ifdef __STRICT_ANSI__ 
#undef __STRICT_ANSI__ 
#include <cstdio> 
#define __STRICT_ANSI__ 
#else 
#include <cstdio> 
#endif 

+0

いいえ。プロジェクトで作業している誰かがC++ 11タイプを使用しているので、私はC++ 11フラグが必要です。フラグでファイルを開き、それをファイルポインタに変換する必要があるため、fdopenが必要です。 fopen()を使用してファイルを排他的な作成として開くことはできません。私はうんざりしているように見えます。あなたはこれを試すことができます – AlastairG

+0

: '__STRICT_ANSI__' 'の#include '' の#define __STRICT_ANSI__' #undefのそれは非常にエレガントではありませんが、...場合、それには、あまりにも答えにそれを追加します動作します誰かを助けるかもしれない。 – Ale

8

何をしても、__STRICT_ANSI__フラグをつけてください。そのシンボルはGCCによって制御されます。あなたはGCCにそれを定義させ、それをそのままにしておくべきです。

あなたが実際に探しているのは_POSIX_C_SOURCE機能テストマクロです。あなたは、fdopenがC言語標準で定義されていないことがわかります。あなたがC++ 11プログラムを書いていることをGCCに伝えると、GCCはその言語で定義されていない関数を定義しようとしない "strict"モードに入ります。これはあなた自身のコードと名前の衝突を避けるためです。例えば、有効なC++ 11プログラムはfdopenという独自の関数を自由に定義することができます。fdopenはその言語の予約済み識別子ではないからです。

しかし、fdopenは、C言語標準を含むが別個の標準であるPOSIXによって定義されるである。 fdopenのようなPOSIX関数を使用するアプリケーションを書くときには、システムにPOSIXアプリケーションを書くつもりであることを伝える必要があります。これは、_POSIX_C_SOURCEフィーチャーテストマクロが入る場所です。すべてのソースファイルの先頭に、ヘッダーを含める前に、このマクロを適切な値に定義します。例:

#define _POSIX_C_SOURCE 200112L 

この定義で使用する値は、対象とするPOSIXのバージョンによって異なります。ターゲットとするバージョンが不明な場合は、ホストシステムが準拠しているものと同じバージョンをターゲットにすることができます。あなたは、シェルからgetconfを実行することによってこれを決定することができます

$ getconf _POSIX_VERSION 
200809L 
$ _ 

はここで、私のシステムは、POSIXバージョン200809L(すなわちPOSIX.1-2008)に準拠していると言われます。私は#define _POSIX_C_SOURCE 200809Lを私のソースコードに入れることができ、私のシステムでサポートされているすべての標準機能が利用可能になると確信しています。

+0

WindowsのMinGW gccバージョン4.7.0では動作しません。 – Ale

+1

@Ale:これは、Newlib開発者(CygwinとMinGWが使用するCライブラリを書く)がPOSIX機能テストマクロの目的を理解していないからです。これはNewlibに何年も問題がありましたが、何度も指摘されています(面白い例として、http://cygwin.com/ml/cygwin/2011-10/msg00145.htmlを参照してください;全体スレッドは素晴らしいです!)彼らは徐々にヘッダーファイルを修正しようとしています。残念ながら、まだ 'fdopen'が宣言されている' 'は固定されていません。 –

+2

@Ale:修正:MinGWはNewlibを使用しません。しかし、ヘッダファイルには同じ誤りがあります(おそらく、Cygwinとの共通の祖先が原因かもしれませんし、プログラマがPOSIX機能テストマクロを理解できないこともあります)。いずれにしても、MinGW開発者はPOSIX準拠のシステムを開発していないと主張しているため、MinGWはあまり参考にならない例です。 POSIXに準拠していないシステムでPOSIXの機能( 'fdopen'など)をテストするのは無意味です。 –

関連する問題