C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: C++の関数の引数


(過去ログ 81 を表示中)

[トピック内 10 記事 (1 - 10 表示)]  << 0 >>

■47667 / inTopicNo.1)  C++の関数の引数
  
□投稿者/ たかけん (1回)-(2010/03/10(Wed) 20:35:25)

分類:[C/C++] 

初めまして。VisualStudio2005 で C++ のコードを書いております。
このたび、どうしても解決できない疑問が発生したため、質問させていただきます。

関数定義の際に、引数はありません、ということを明示的に記述するために、引数に、以下のように書いておりました。
----
foo.h
extern VOID foo( VOID );
----
foo.cpp
VOID foo( VOID )
{
〜〜
}
----
VOID は typedef void VOID; となっております。
また、クラスの関数でも同様に記述しております。

VC++ では問題ないのですが、インテルコンパイラでは、エラー扱いとされてしまいました。

この記述方法は、C++の文法上間違いなのでしょうか?

引用返信 編集キー/
■47670 / inTopicNo.2)  Re[1]: C++の関数の引数
□投稿者/ επιστημη (2466回)-(2010/03/10(Wed) 22:06:17)
επιστημη さんの Web サイト
> インテルコンパイラでは、エラー扱いとされてしまいました。

どんなエラー・メッセージですか?

> この記述方法は、C++の文法上間違いなのでしょうか?

コンパイラがvoidを型として扱うか、が問題なのでしょう。
# 私見では、typedef void VOID を許してもいいように思えます。

引用返信 編集キー/
■47672 / inTopicNo.3)  Re[2]: C++の関数の引数
□投稿者/ 774RR (482回)-(2010/03/10(Wed) 22:18:21)
2010/03/10(Wed) 22:19:57 編集(投稿者)

どうやらダメということのようですだよ。
8.3.5 関数 (宣言)
仮引数並びが (void) の場合、空の仮引数並びと同等 (つまり引数を持たない)
この特殊ケースを除き void は仮引数の型になってはならない。

JIS X 3014 のフォントだと識別困難なのだが ISO/IEC 14882 のフォントだと
The parameter list <code>(void)</code> is equivalent と書いてあることと判別でき、
つまり、引数なしを指定するのは (void) と書いた場合に限る、と読むことができる。

gcc-4.3.2 @ cygwin では 'anonymous' has incomplete type というエラーになる。

s/判断/判別/g
引用返信 編集キー/
■47676 / inTopicNo.4)  Re[3]: C++の関数の引数
□投稿者/ επιστημη (2468回)-(2010/03/11(Thu) 08:52:32)
επιστημη さんの Web サイト
> 8.3.5 関数 (宣言)
> 仮引数並びが (void) の場合、空の仮引数並びと同等 (つまり引数を持たない)
> この特殊ケースを除き void は仮引数の型になってはならない。

なるほど、f(void)のvoidは「引数なし」を示すためであり、
「void型の引数を与える」と読んではイカンと。
さらに、f(void)のばやい、"void"と書くことが「引数なし」を示すんだと。
そーなると #define VOID void だったらおっけぃてことになるますね。

「引数なし」を表現するのに、Cだと確かに(void)だけども C++なら()で
構わんのだから、あたしゃわざわざf(void)て書いたためしがありんせん。

引用返信 編集キー/
■47677 / inTopicNo.5)  Re[4]: C++の関数の引数
□投稿者/ 774RR (483回)-(2010/03/11(Thu) 09:20:45)
> そーなると #define VOID void だったらおっけぃてことになるますね。
はい、問題ないことを検証済みです。
(プリプロセス展開後に)文字通り (void) と記載されていれば、ということっすね。

int func(VOID) { ... } だと (typedef void VOID; であるとき)
・1つの引数を取り、呼び出し側での省略不可
・その引数の型は VOID であり、呼び出される側(関数定義側)で使用していないので <無名>
・型 VOID は不完全型である
と解釈しているわけで、エラー「 <無名> の型は不完全型である」となるっす。

たぶんその辺の厳密規定は C++ 固有事情があっての話なのだと思われるっす。
特に function template に void が適用される場合を想定してると思われるっす。
template<typename T> T func(T a) { return a; }
func<void>(/*arg*/); // arg に何を指定するお?

C++ だけで話が済んでいるのであれば f() と書いて無問題なんだけども
C++/C 混在になると f(void) と書きたくなるケースが見受けられるので、気持ちはわかる。
だけど、「できない」と書いてあるので VS2005 のほうが実装ミスと解釈すべきだね。
引用返信 編集キー/
■47681 / inTopicNo.6)  Re[5]: C++の関数の引数
□投稿者/ 774RR (484回)-(2010/03/11(Thu) 09:56:29)
関数定義の際 (関数定義が関数原型宣言を兼ねる場合を含む)
・ C では <無名> 引数が許されていない (C89/C99 とも)
・ C++ では <無名> 引数が許されている
という事情もありそう (っていうかこっちが主だね)

C++ の場合 void func(void) {} の読み方を定めておかないとあいまいになるわけですな。
・引数が無い
・void 型引数があって、その引数名として <無名> を採用している (C ではできない解釈)
c89 との互換性維持のため前者を採用し、後者を禁じている、と。
文字通りに (literally) (void) と書いた場合のみ前者、とすることで拡張性を維持してる、
ということですな (うん、オラも勉強になっただよ)
引用返信 編集キー/
■47682 / inTopicNo.7)  Re[5]: C++の関数の引数
□投稿者/ επιστημη (2469回)-(2010/03/11(Thu) 09:58:48)
επιστημη さんの Web サイト
> 「できない」と書いてあるので VS2005 のほうが実装ミスと解釈すべきだね。

2008(VC9), 2010(VC10RC)でもやってみた。

typedef void VOID;
VOID f(VOID) {}

int main() { f(); }

…通っちゃいますた (ノ∀`)アチャー

引用返信 編集キー/
■47683 / inTopicNo.8)  Re[6]: C++の関数の引数
□投稿者/ 774RR (485回)-(2010/03/11(Thu) 10:14:25)
まあそうなんだけど、言語規格書上「未定義の動作」をどう実装しても処理系作者の勝手なわけで
・ Intel C, GNU CC は C++ 規格書との整合を優先した
・ Microsoft C は C++ 規格書との整合より既存 C ソースとの互換性優先した
だけの話、だとオラは思う。
# -Za オプションつけてもコンパイル通っちゃうな・・・
# cl -help の -Za オプションの解説が間違ってる・・・爆

修正提案投げてもいいけどたぶん却下されそうな希ガス。
引用返信 編集キー/
■47684 / inTopicNo.9)  Re[7]: C++の関数の引数
□投稿者/ aetos (247回)-(2010/03/11(Thu) 10:35:05)
No47683 (774RR さん) に返信
> まあそうなんだけど、言語規格書上「未定義の動作」をどう実装しても処理系作者の勝手なわけで
> ・ Intel C, GNU CC は C++ 規格書との整合を優先した
> ・ Microsoft C は C++ 規格書との整合より既存 C ソースとの互換性優先した
> だけの話、だとオラは思う。
> # -Za オプションつけてもコンパイル通っちゃうな・・・
> # cl -help の -Za オプションの解説が間違ってる・・・爆
>
> 修正提案投げてもいいけどたぶん却下されそうな希ガス。

型名を大文字化したがるのは MS 文化だから…と思ったけど、それも最近は変わってきているようですね。
ほんの一例ですが、興味深いかも。

古い英語版ドキュメントに基づく翻訳版
http://msdn.microsoft.com/ja-jp/library/cc429110.aspx

最新の英語版ドキュメント
http://msdn.microsoft.com/en-us/library/ms683179.aspx
引用返信 編集キー/
■47754 / inTopicNo.10)  Re[8]: C++の関数の引数
□投稿者/ たかけん (2回)-(2010/03/13(Sat) 02:10:54)
επιστημη様、774RR様、aetos様
ご返答いただきありがとうございました。

インテルコンパイラでのエラーの詳細は、失念してしまいました。申し訳ございません。
ちなみに、gcc3 では、エラーなくビルドできております。

もう一度、VOID の定義を調べてみたのですが、VC++ では、しっかり
#define VOID void
となっておりました……
昔、typedef で見た気がしていたのですが。

実は、サーバーコード(Linux)もありまして、そちらが typedef にて、定義しておりました。
これが、問題だった様です。

引数に void を書いても間違いではないこと、定義の仕方によって、挙動がかわることがわかり
質問をさせていただいて、本当によかったと思います。

重ね重ね、ありがとうございました。
解決済みとさせていただきます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -