【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください

ある本に次のような例題がありました。
「不正なヘッダ」
#define max(a,b) ((a)>(b)?(a):(b)) EOF
「正しいヘッダ」
#define max(a,b) ((a)>(b)?(a):(b)) ←Enterキー
EOF

ここで”不正なヘッダ”でコンパイルするとエラー表示のメッセージが表示され、その理由は”前処理指令は改行文字で終了しなければならない”との事です。又処理系によっては”不正なヘッダ”(改行文字なし)が許されるものもあると書かれていました。しかしその場合、可搬性は損なわれると書いてありました。私の処理系はRedHat Linuxでviを使っています。私の処理系で”不正なヘッダ”でコンパイルしてもなんらメッセージが無くコンパイルできました。
はたしてこの場合可搬性はあるのでしょうか?
又その本には”ソースファイルの最後の行にも必ず改行文字をつけよう”と書いてありました。しかしviを使っていてcプログラムとしてソースファイルを書いている時、最後に改行文字を入れた事はありませんでした。この場合も可搬性は失われるのでしょうか。
宜しく願います。

A 回答 (5件)

vi は最後の行に*勝手に*改行を入れるんじゃなかったかな.


どうにも気になったら, 改行が入っているかどうか自分で確認してください.
    • good
    • 0

>可搬性はあるのでしょうか?


・・・と聞かれれば、「ない」とお答えすることになります。

コンパイラも方言があります。
ここで言う方言は、言語上でなく、行末の改行などの扱い方です。
経験上、複数のコンパイラを使ってますと必ず問題になります。
改行以外によくある問題は、コメントのネストや文中のEOF、コードとみなされない文字の扱い、インクルードファイル側の問題などです。
C言語だけではありません。
アセンブリ言語にも同様の問題がよく発生します。
makeがソースファイルを吐き出すときなどは、特に注意が必要です。
問題を回避するには、”安全な書き方”しかありません。
    • good
    • 0

前処理指令云々ではなく、空ではないソースファイルが改行以外で終わる場合、未定義の動作になります。

例えば、

int main(void)
{
 ...
}<EOF>

のような場合も同様に未定義の動作になります。
未定義の動作ですから、当然可搬性はありません。
    • good
    • 0

世の中に


A. ヘッダ(ソースコード)ファイルの末尾に改行がないとエラーになる処理系
B. ヘッダ(ソースコード)ファイルの末尾に改行がなくてもエラーにならない処理系
が存在するとして、
ソースコード(ヘッダ)の最後に改行を入れておけば処理系AでもBでもエラーにならないのに対して、改行を入れないでおくと処理系BではOKですが処理系AではNGです。
なので、別に改行を入れたって困るわけでなし入れておきましょう(その方が安全)ということです。
上の例で処理系Bを使っていたからエラーになっていなかったコードを処理系Aの環境に持って行ったらエラーでコンパイルできなくなることを「可搬性がない」と言っています。

あなたが書いた「不正なヘッダ」は、たまたまあなたの環境が上で言う処理系Bの環境だったからよかったわけで、世の中のどこかにある処理系Aに持ち込んだとたんにエラーになるのです。つまり「可搬性がない」(あなたのプログラムは処理系Aの環境に持ち込もうと思ったら改行を追加して回らないとエラーでコンパイルできない)ということです。

しつこいようですが、「可搬性がある」というのはある環境で(たまたま)動いたのでどうだという話ではなくて、世の中のおよそ思いつくどこに持っていっても動くようになっているという状態を指し示しています。
だから、自分の環境でたまたまコンパイルできたからと言って「可搬性がある」などとは言えません。あなたの知らない、でもその本の著者が知っているある環境でも動くようにしておくとよいよ、ということです。
    • good
    • 0

#defineで定義するなら改行は必須でしょう。


なぜなら一行単位で解析されるものだからです。
そもそも2行以上になるときはなぜ行末に\が必要なのでしょうか?

それを考えたら自明かと思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報