• 締切済み

C++の組込みマクロのassert()が使えない

こんにちは。 CygwinでC++開発を行っているのですが、C++の関数型マクロであるassert()が使えなくて困っています。 main関数を含むソースファイルに、 #include assert.h を記述しておけば使えるはずなのですが、そのソースファイルから実行ファイルを、 g++コマンドでビルドしようとすると、以下のようなエラーが出ます。 ------------------------------------------------------------ $ g++ test03-STLの使用.cpp /cygdrive/c/Users/Kei/AppData/Local/Temp/cckwDP4e.o:test03-STLの使用.cpp:(.text+0x904): undefined reference to `___assert_func' collect2: ld はステータス 1 で終了しました ------------------------------------------------------------ test03-STLの使用.cpp のmain関数は、以下の通りです。 ------------------------------------------------------------ int main() { string s="ABC DEF\nGH\tIJ"; reverse(s.begin(), s.end() ); assert(s=="JI\tHG\nFED CBA"); cout<<s return 0; } ------------------------------------------------------------ ちなみに、実際にインクルードされる /usr/include/assert.h の内容は以下のようになっていました。 ------------------------------------------------------------ /* assert.h */ #ifdef __cplusplus extern "C" { #endif #include "_ansi.h" #undef assert #ifdef NDEBUG /* required by ANSI standard */ # define assert(__e) ((void)0) #else # define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ __ASSERT_FUNC, #__e)) # ifndef __ASSERT_FUNC /* Use g++'s demangled names in C++. */ # if defined __cplusplus && defined __GNUC__ # define __ASSERT_FUNC __PRETTY_FUNCTION__ /* C99 requires the use of __func__. */ # elif __STDC_VERSION__ >= 199901L # define __ASSERT_FUNC __func__ /* Older versions of gcc don't have __func__ but can use __FUNCTION__. */ # elif __GNUC__ >= 2 # define __ASSERT_FUNC __FUNCTION__ /* failed to detect __func__ support. */ # else # define __ASSERT_FUNC ((char *) 0) # endif # endif /* !__ASSERT_FUNC */ #endif /* !NDEBUG */ void _EXFUN(__assert, (const char *, int, const char *) _ATTRIBUTE ((__noreturn__))); void _EXFUN(__assert_func, (const char *, int, const char *, const char *) _ATTRIBUTE ((__noreturn__))); #ifdef __cplusplus } #endif ------------------------------------------------------------ Borland C++ Compilerのbcc32コマンドでは、先ほどのソースファイルから実行ファイルをビルドすることができたので、何が問題なのかが分かりません。 以上の件について何かご存知の方がいらっしゃれば、是非教えて頂きたいと思います。 では、よろしくお願い致します。

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「完全なソース」も出してもらえませんか?

MetalLover
質問者

お礼

御回答ありがとうございます。 返信が遅くなって申し訳ございませんでした。 完全なソースは以下の通りです。 #include <iostream> #include <cassert> #include <string> using namespace std; int main() { string s="ABC DEF\nGH\tIJ"; reverse(s.begin(), s.end() ); assert(s=="JI\tHG\nFED CBA"); cout<<s; return 0; } 何か分かりましたら、よろしくお願い致します。

  • 500cii
  • ベストアンサー率50% (14/28)
回答No.1

リンク時の設定のミスではないかと思うのですが、私にはよくわかりません。 -vオプションを付ければ、ビルド時の色々な設定が出てくるので、それを載せれば誰か分かる人が出てくるかもしれません。

MetalLover
質問者

お礼

御回答ありがとうございます。 >-vオプションを付ければ、ビルド時の色々な設定が出てくるので、それを載せれば誰か分かる人が出てくるかもしれません。 記載したソースファイルから実行ファイルを、g++コマンドに-vオプションをつけて、ビルドしようとた時の結果は以下の通りです。 ------------------------------------------------------------ Kei-Valuestar@Kei: ~/C_and_C++_Programs/Cpp_Programs $ g++ -v assert.cpp /bin/../lib/gcc/i686-pc-cygwin/3.4.4/specs から spec を読み込み中 コンフィグオプション: /managed/gcc-build/final-v3-bootstrap/gcc-3.4.4-999/configure --verbose --program-suffix=-3 --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug スレッドモデル: posix gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) /bin/../lib/gcc/i686-pc-cygwin/3.4.4/cc1plus.exe -quiet -v -iprefix /bin/../lib/gcc/i686-pc-cygwin/3.4.4/ -D__CYGWIN32__ -D__CYGWIN__ -Dunix -D__unix__ -D__unix -idirafter /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api -idirafter /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/../../include/w32api assert.cpp -quiet -dumpbase assert.cpp -mtune=pentiumpro -auxbase assert -Wno-deprecated -version -o /cygdrive/c/Users/kei/AppData/Local/Temp/ccNI6mgL.s 存在しないディレクトリ "/bin/../lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/include" を無視します 重複したディレクトリ "/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++" を無視します 重複したディレクトリ "/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/i686-pc-cygwin" を無視します 重複したディレクトリ "/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/backward" を無視します 重複したディレクトリ "/usr/lib/gcc/i686-pc-cygwin/3.4.4/include" を無視します 存在しないディレクトリ "/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/include" を無視します 重複したディレクトリ "/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/../../include/w32api" を無視します #include "..." の探索はここから始まります: #include <...> の探索はここから始まります: /bin/../lib/gcc/i686-pc-cygwin/3.4.4/include/c++ /bin/../lib/gcc/i686-pc-cygwin/3.4.4/include/c++/i686-pc-cygwin /bin/../lib/gcc/i686-pc-cygwin/3.4.4/include/c++/backward /bin/../lib/gcc/i686-pc-cygwin/3.4.4/include /usr/local/include /usr/include /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api 探索リストの終わり GNU C++ version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) (i686-pc-cygwin) compiled by GNU C version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/as.exe -o /cygdrive/c/Users/kei/AppData/Local/Temp/cccIcGlN.o /cygdrive/c/Users/kei/AppData/Local/Temp/ccNI6mgL.s /bin/../lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic --dll-search-prefix=cyg /bin/../lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -L/bin/../lib/gcc/i686-pc-cygwin/3.4.4 -L/bin/../lib/gcc -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/bin/../lib/gcc/i686-pc-cygwin/3.4.4/../../.. -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. /cygdrive/c/Users/kei/AppData/Local/Temp/cccIcGlN.o -lstdc++ -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc /cygdrive/c/Users/kei/AppData/Local/Temp/cccIcGlN.o:assert.cpp:(.text+0x3ad): undefined reference to `___assert_func' collect2: ld はステータス 1 で終了しました Kei-Valuestar@Kei: ~/C_and_C++_Programs/Cpp_Programs ------------------------------------------------------------ 引き続き、よろしくお願い致します。

関連するQ&A

  • 組み込みマイコン

    組み込みマイコンでプログラミングしていると以下の様なエラーがでるのですが原因が分かりません。 教えてください。 C:\WorkSpace\sample\sample\sample.c(33) : C5020 (E) Identifier "PORTA" is undefined C5020 (E) Identifier "名前" is undefined シンボル"名前"の定義がありません。 プログラムは以下のようになっています。マイコンはAKI-RX621。 /***********************************************************************/ /* */ /* FILE :sample.c */ /* DATE :Tue, Apr 23, 2013 */ /* DESCRIPTION :Main Program */ /* CPU TYPE :RX62N */ /* */ /* This file is generated by Renesas Project Generator (Ver.4.53). */ /* NOTE:THIS IS A TYPICAL EXAMPLE. */ /* */ /***********************************************************************/ //#include"iodefine,h" //#include "typedefine.h" #ifdef __cplusplus //#include <ios> // Remove the comment when you use ios //_SINT ios_base::Init::init_cnt; // Remove the comment when you use ios #endif void main(void); #ifdef __cplusplus extern "C" { void abort(void); } #endif void main(void) { long int t; /* 変数tの設定 */ PORTA.DDR.BYTE=0xff; /* ポートAの端子は全て出力端子に設定する */ PORTA.DR.BYTE=0x00; /* ポートAの出力端子を初期設定する */ while(1) /* 無限ループ */ { for(t=0;t<6000000;t++); /* 約1秒間の時間保持 */ PORTA.DR.BYTE=0x01; /* LED(赤)を点灯、LED(緑)を消灯 */ for(t=0;t<6000000;t++); /* 約1秒間の時間保持 */ PORTA.DR.BYTE=0x02; /* LED(緑)を点灯、LED(赤)を消灯 */ } } #ifdef __cplusplus void abort(void) { } #endif

  • AKI-h8 3069f C言語 HEW マイコン DIPスイッチで LED ON_OFF プログラム 「組込みI/O制御演習」

    こんにちは。 標記開発環境でマイコンを制御しています。 下記ソースでDIPスイッチのONOFFでLEDを点灯させたいのですが うまくいきません。 多分 P4DR.BIT.B0 =~P5DR.BIT.B0; の部分の修正が必要かと思うのですが。 どなたかご存知の方よろしくお願いします。 //------------------ #include "iodefine.h" void main(void); #ifdef __cplusplus extern "C" { void abort(void); } #endif void main(void) { P5DDR = 0; P5PCR.BYTE = 0xff; P4DDR = 0xff; while(1) { P4DR.BIT.B0 =~P5DR.BIT.B0; } } #ifdef __cplusplus void abort(void) { } #endif

  • C#から、C++作成dll内の関数を呼び出す方法

    C#から、C++で作成したdll内の関数を呼び出す方法は、以下の方法で実現できました。(メッセージボックスで "10" が表示されました) [C++側のヘッダファイル] #ifdef CPPDLL_EXPORTS #define CPPDLL_API __declspec(dllexport) #else #define CPPDLL_API __declspec(dllimport) #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ CPPDLL_API int fnCppDll(); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ [C++側のソースファイル] CPPDLL_API int fnCppDll() { return 10; } [C#側] using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApp1 { public partial class Form1 : Form { [DllImport("CppDll.dll")] public static extern int fnCppDll(); public Form1() { InitializeComponent(); } private void buttonGo_Click(object sender, EventArgs e) { int n = fnCppDll(); MessageBox.Show(n.ToString()); } } } 今回お聞きしたいのは、int型ではなく、C++側で型を定義されたクラスのオブジェクト(の参照)を返す関数を、C#側から呼び出し、それをどうやってC#で受け取るかを教えていただきたいのです。 具体的には以下のように実装してみました。 [C++側のヘッダファイル] #ifdef CPPDLL_EXPORTS #define CPPDLL_API __declspec(dllexport) #else #define CPPDLL_API __declspec(dllimport) #endif class CPPDLL_API CCppDll { public: int data; CCppDll(void); }; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ CPPDLL_API CCppDll& fnCppDll(); // C#が参照渡しということで、参照を返すようにした。 #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ [C++側のソースファイル] CPPDLL_API CCppDll& fnCppDll() { CCppDll* a = new CCppDll(); return *a; } CCppDll::CCppDll() : data(11) // メンバーは 11 で初期化 { } [C#側] using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApp1 { // ビルドエラーが起きるないように、とりあえず、C++と同じ(ような)クラスを定義 public class CCppDll { public int data; } public partial class Form1 : Form { [DllImport("CppDll.dll")] public static extern CCppDll fnCppDll(); public Form1() { InitializeComponent(); } private void buttonGo_Click(object sender, EventArgs e) { int n; CCppDll cls = fnCppDll(); // ※ n = cls.data; MessageBox.Show(n.ToString()); } private void buttonCancel_Click(object sender, EventArgs e) { Close(); } } } 実装しながらも、「これじゃあ、ダメだろうな。いかにもダメだな」と思った通り、上の※の部分で以下の例外が発生しました。 ------- 例外(ここから) ------- マネージド デバッグ アシスタント 'FatalExecutionEngineError' : 'ランタイムの重大なエラーが発生しました。エラーのアドレスは 0xcc9ff5a2、スレッド 0x36c8 です。エラー コードは 0xc0000005 です。これは CLR のバグであるか、またはユーザー コードのアンセーフまたは確認不可能な部分にバグがある可能性があります。このバグの一般的な原因には、スタックが壊れる可能性のある COM-interop または PInvoke のユーザー マーシャリング エラーが含まれています。' ------- 例外(ここまで) ------- 明らかに基本的なことが分かっていないことから起因するエラーと思われますが、具体的にどう実装すれば、正常に動きますか。(メッセージボックスで "11" を表示) よろしくお願いします。

  • error LNK2001について

    C++ の勉強中です。 error LNK2001問題がありました。問題点も分からないから、 分かった方に教えていただけないでしょうか? ソースも添付します。環境はVS2005 express edition まず、ヘッダファイルです。ファイル名は、myheader.h #ifndef __MYHEADER_H__ #define __MYHEADER_H__ #define includeshow(x) \ { \ s.show(x); \ } class Sample{ public: void show(char * parameter); }; extern Sample s; #endif //------------------------------------------------ 次に、Sample.cppです。 #include "myheader.h" #include <stdio.h> void Sample::show(char *parameter){ printf("in show func"); } //----------------------------------------------- 最後にTest.cppです。 #include "myheader.h" #include <stdio.h> int main(){ includeshow("ppppp"); } これで error LNK2001: 外部シンボル ""class Sample s" (?s@@3VSample@@A)" は未解決です。というエラーが出ています。 よろしくおねがいします。

  • Cの関数をC++とCのどちらからでも呼べるようにするには?

    お世話になります。 環境はVC6.0となります。 C++で作成したプログラムから、Cで作成したDLLを呼び出す場合、DLL側のプロトタイプ宣言に「extern "C"」を付加する必要があると認識していますが、 呼び出し側がC++かC言語が分からない場合、Cで作成するDLLにはどのように記述するのが一般的(標準的)でしょうか? ちなみに調べてみたところ、 以下のように、「__cplusplus」でくくる方法もあるようですが、C++の標準仕様ではないとの記載がありました。 #ifdef __cplusplus extern "C" { #endif int function(int num); int function2(int num); int function3(int num); #ifdef __cplusplus } #endif よろしくお願いします。

  • Visual C++ ヘッダー情報の反映

    ヘッダー内の定義(の変更)が反映されないことがあります。 例えば、 "stdafx.h"において #define a 123 と定義して、関数項目main.cppとfunc.cpp両方でaを使うとします。 もちろんどちらも最初に#include "stdafx.h"とインクルードしています。 ですがdefine定義を#define a 456のように変更し実行すると、 main.cpp内ではa=456で動作し、func.cpp内ではa=123で動作する。 というような症状がしばしば現れます。 Visual stadio 2008でプログラミングしています。 c++ 6.0のときも同様の症状が現れていたのですが、何か問題があるのでしょうか? よろしくお願いします。

  • C++ ポインタについて質問です

    c++ で三角形の周囲を計算で出したいのですが、エラーがでてしまいます。うまくpoint が機能していないようなのですがどこが悪いのでしょうか?? main.cppの中身 #ifdef TRIANGLE_DONE { // Define three points Point p1 = {1, 3}, p2 = {-2, -2}, p3 = {3, -1}; // Create a Triangle variable Triangle t = {p1, p2, p3}; // Now, test the perimeter() function assertDoubleEqualsMsg("Check perimeter of Triangle", 15.4021, perimeter(t), 1E-5); } #else cerr << "Define the Triangle structure. Then, uncomment #define TRIANGLE_DONE in h19.h" << endl; #endif hの中身 #define TRIANGLE_DONE struct Triangle{ Point a, b, c; }; #ifdef TRIANGLE_DONE /** * Calculates the perimeter of the Triangle t. * @param t the Triangle to examine. * @return the perimeter. */ double perimeter(const Triangle& t); #endif h19.cppのなかみ double premiter(const Triangle& t) { double p = 0; p = t.p1 + t.p2 + t.p3; return p; } 必ず "Define the Triangle structure. Then, uncomment #define TRIANGLE_DONE in h19.h" のコメントがでてしまいます。どのように改善すれば良いでしょうか?

  • 関数名の名前の衝突について。

    こんにちは。 関数名の名前の衝突で困っています。 以下のような感じで名前空間でUNICODEでマルチバイト版とで定義しています。 Win32APIのGetFileSize関数を例に説明します。 Win32APIのGetFileSize関数はファイルハンドルを指定しなければいけないので 直接ファイル名からファイルサイズを取得できるように同じ名前の関数を 名前空間で区切って以下のようにしました。 ---------------- Foo.h -------------- #include <windows.h> namespace Foo { #ifdef UNICODE     #define GetFileSize GetFileSizeW #else     #define GetFileSize GetFileSizeA #endif // !UNICODE     DWORD GetFileSizeW( wchar_t* const szFilename ){ return 0 ;}     DWORD GetFileSizeA( char* const szFilename ){ return 0 ;} } ---------------- Foo.h -------------- 上記の関数はちゃんと動作することは確認できましたが、本来のWin32APIの DWORD GetFileSize( HANDLE hFile, LPDWORD lpFileSizeHigh ) を ---------------- main.cpp -------------- #include <windows.h> #include "Foo.h" void func( HANDLE hFile ) {     DWORD dwFilesize = ::GetFileSize( hFile, NULL ) ; } ---------------- main.cpp -------------- 上記のように利用しようとすると、 error C2039: 'GetFileSizeW' : '`global namespace'' のメンバではありません。 error C3861: 'GetFileSizeW': 識別子が見つかりませんでした というエラーが出てきてしまいます。 これを解決するためにはUNICODEでマルチバイト版とで再定義してしまっている #defineの部分を削除するしかないのでしょうか? もし解決方法がありましたら教えていただけないでしょうか?

  • C/C++関数間でのStringクラスの扱い

    以下のようなコードを実行してみましたが思い通りに動いてくれません. "sample"という文字列がstrへとコピーされると思ったのですが. stringクラスのc_str()メソッドはconst char*だと言っているので無理矢理キャストしたのが原因でしょうか.stringクラスは記憶領域を自動で変更してくれるのではないのですか.それともこの挙動は仕様ですか. -------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) {     string str("");     func((char *)str.c_str());     cout << "String: " << str << endl;     return EXIT_SUCCESS; } int func(char *buf) {     buf = "sample";     return 0; } -------- 以上コード --------

  • c++ クラスに関してです。

    うまくクラス同士を連動させることができなくてエラーが出てしまいます。 どこが間違えているのかアドバイスくださると助かります。 #ifndef H22_H_ #define H22_H_ #include <string> #include "account.h" class Bank { public: Bank(); void deposit(double amount, const std::string& accountType); void withdraw(double amount, const std::string& accountType); void transfer(double amount, const std::string& accountType); double getBalance() const; double getSavingsBalance() const; double getCheckingBalance() const; private: Account checking, savings; }; #endif #ifndef ACCOUNT_H #define ACCOUNT_H #include <string> #include "account.h" class Account{ public: Account(); Account(double &amout); double deposit(double amount); double getBalance() const; double withdraw(double amount); double balance; private: }; #endif #include <iostream> #include "acount.h" using namespace std; Account::Account { balance = 0; } Account::Account(double amount) { balance = amount; } Account::double deposit() const { return balance; } Account::double getBalance(double balance) { balance += amount; return balance; } Account::double withdraw(double amount) { if(amount > balance) { balance -= 5; return balance; } elese { balance -= amount; return balance; }} h22.h の中身 #include <string> #include "h22.h" #include "account.h" #include <stdexcept> using namespace std; Bank::Bank() { Account checking; Account saving; } void Bank::deposit(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") throw invalid_argument("Does not compute"); else if(accountType == "S") savings.balance += amount; else if(accountType == "C") checking.balance += amount; } void Bank::withdraw(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") throw invalid_argument("Does not compute"); else if(accountType == "S") savings.balance -= amount; else if(accountType == "C") checking.balance -= amount; } void Bank::transfer(double amount, const string& accountType) { if (accountType != "S" && accountType != "C") { throw invalid_argument("Does not compute");} else if(accountType == "S") { savings.balance += checking.balance; savings.balance = 0;} else if(accountType == "C") { checking.balance += amount; checking.balance = 0;} } double Bank::getBalance() const { return getBalance(); } double Bank::getSavingsBalance() const { return savings.getBalance(); } double Bank::getCheckingBalance() const { return checking.getBalance(); } メイン.cpp http://pastebin.com/rQTj8xciです。 なにかヒントやアドバイスお願いします

専門家に質問してみよう