• ベストアンサー

前処理指令行の末尾の改行の必要性

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

質問者が選んだベストアンサー

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

vi は最後の行に*勝手に*改行を入れるんじゃなかったかな. どうにも気になったら, 改行が入っているかどうか自分で確認してください.

その他の回答 (4)

  • yphkz4063
  • ベストアンサー率23% (34/144)
回答No.5

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

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

前処理指令云々ではなく、空ではないソースファイルが改行以外で終わる場合、未定義の動作になります。例えば、 int main(void) {  ... }<EOF> のような場合も同様に未定義の動作になります。 未定義の動作ですから、当然可搬性はありません。

  • dummyplug
  • ベストアンサー率58% (134/230)
回答No.2

世の中に A. ヘッダ(ソースコード)ファイルの末尾に改行がないとエラーになる処理系 B. ヘッダ(ソースコード)ファイルの末尾に改行がなくてもエラーにならない処理系 が存在するとして、 ソースコード(ヘッダ)の最後に改行を入れておけば処理系AでもBでもエラーにならないのに対して、改行を入れないでおくと処理系BではOKですが処理系AではNGです。 なので、別に改行を入れたって困るわけでなし入れておきましょう(その方が安全)ということです。 上の例で処理系Bを使っていたからエラーになっていなかったコードを処理系Aの環境に持って行ったらエラーでコンパイルできなくなることを「可搬性がない」と言っています。 あなたが書いた「不正なヘッダ」は、たまたまあなたの環境が上で言う処理系Bの環境だったからよかったわけで、世の中のどこかにある処理系Aに持ち込んだとたんにエラーになるのです。つまり「可搬性がない」(あなたのプログラムは処理系Aの環境に持ち込もうと思ったら改行を追加して回らないとエラーでコンパイルできない)ということです。 しつこいようですが、「可搬性がある」というのはある環境で(たまたま)動いたのでどうだという話ではなくて、世の中のおよそ思いつくどこに持っていっても動くようになっているという状態を指し示しています。 だから、自分の環境でたまたまコンパイルできたからと言って「可搬性がある」などとは言えません。あなたの知らない、でもその本の著者が知っているある環境でも動くようにしておくとよいよ、ということです。

  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.1

#defineで定義するなら改行は必須でしょう。 なぜなら一行単位で解析されるものだからです。 そもそも2行以上になるときはなぜ行末に\が必要なのでしょうか? それを考えたら自明かと思います。

関連するQ&A

  • シンボル名の再定義のためにコンパイルエラー

    Motifのヘッダー(Aとする)にMax(a,b)というdefineがあり、そのヘッダーの(恐らく)後にincludeしている某クラスライブラリのヘッダー(Bとする)の関数定義にMax(a,b)というのがあります。 そのため、B中のMaxでは、Aのdefineが展開されてしまい、コンパイルエラーになってしまいます。 どちらのヘッダーも修正するわけにはいかないのですが、includeの順番を変えようにも、どこでincludeされているのか調査するのも難航しています。 何か回避策、もしくは解析するのに便利なツールなどご存知でしたら教えてください。 なお、開発環境はUNIX(正しくはAIX)です。

  • ヘッダファイルの2重のインクルードについて

    ある書物に「ヘッダファイルを複数回インクルードすると、それを”再定義”することによるエラーになる」と書いてありますたが、以下のようなヘッダファイルを作りそれを数回インクルードしても何ら異状が無くコンパイルできました。 math.h→ヘッダファイル名 #define max(a,b)  ((a)>(b)?(a):(b))→ヘッダファイルの内容 c ファイル #include<stdio.h> #include"math.h"←複数回インクルード #include"math.h"←複数回インクルード int main(void){ int x=1,y=2; printf("max(x,y)=%d\n",max(x,y)); return 0; } 環境としては、RedHat Linuxでviです。 何ゆえ、エラーにならないのか良く解りません。 宜しくお願いします。

  • エクセル 改行から1行に

    A列の各セルに文字が改行されて入力されている場合、それを各セル改行から元の1行に戻す必要がある時、各セル一つずつ元に戻すのは大変なので何か便利な方法は無いでしょうか?

  • phpとhtml間のデータ送信時「テキスト改行」処理について

    自分で調べてみましたが、どうしてもわからず行き詰まりました。 どなたかお知恵を貸して頂ければ幸いです。 【使用ファイル】 a.php php処理 b.html db抽出データ表示とフォーム(編集画面) c.html フォーム入力内容表示(確認画面) データ送信はPOSTとSmarty併用 dbへはMySQLで格納 【変数】 $z テキストエリアの項目値 【流れ】 a.php→b.html→a.php→c.html→a.php→b.html/dbへ格納 1:a.phpでdbよりデータ(テキスト)を抽出し追加、変数$zに格納。 2:Smartyでb.htmlへ$zを送る。送り先はフォーム内のテキストエリア値。 3:$zにテキスト追加で改行発生 (\n発生と予測)。 4:b.htmlからPOSTでa.phpへ。 nl2br($z)処理をし、<br />挿入。 5:Smartyでc.htmlへ$zを送る。 $zには<br>と\nの両方が入っている状態。改行表示される。ブラウザのページソースでは<br />が入っている。 6-1:c.html(POST)→a.php(smarty)→b.html str_replace("<br />,"","$z)で<br />を取り除き\nのみの状態 smartyでb.htmlへ 6-2:c.html(POST)→a.php→db格納  str_replace("<br />,"","$z)で<br />を取り除き\nのみの状態でdbへ格納 6-1,2とも<br />を入れたままだと文字列に<br />が入ってしまう 7:a.php→b.htmlで再度$zを呼び出してみると(1:の処理)<br />を取り除いたはずなのに、ブラウザではきちんと改行表示されている。 ブラウザのページソースに<br />の表示はない 【疑問点】 3:\nは発生してPOSTでa.phpにきているのか? きている種類が\nまたは他の改行文字かどうかを調べる手段はあるのか?バイナリ関連で調べるのか? 6-1:<br />を削除してhtmlへ送っているのに改行表示されるのか? <br />が文字列扱いになるのはなぜか? 6-2:dbでは\nが改行として認識されるのか? 7:\nしか入っていない文字列をブラウザ表示して、なぜ改行表示されるのか? 以上です。考えれば考える程にわからなくなってきました。 どうぞよろしくお願いします。

    • ベストアンサー
    • PHP
  • ポインタによる包含&ヘッダにincludeしない、 場合でtemplateの定義に…

    class Bの宣言をしているヘッダ中で class A; を、前方宣言し、そのポインタだけを持たせ、ソースファイルのほうにclass Aの中身が分かるように、#includeして、ソースファイルに関数の実装やstatic変数の定義を書いていた、とします。 しかし、templateを使う関数についてはコンパイル時に解決できないといけないので、それだけはヘッダに持ってきました。 その時 includeが一切書かれていない、class Bのヘッダ内において class Aのメンバを参照するようなコードを書いたとき クラス外、クラス内、いずれに書いても 正常にコンパイルできました。 通常の関数では当然無理なので、もともとtemplateがコンパイル時解決を強要するものなのでそういう仕様にしててくれてると考えられますが 1.これは、C++の標準仕様でしょうか?それとも処理系依存でしょうか? あと、templateに関して 2.特殊化ならソースにかけるのは標準仕様でしょうか?それとも処理系依存でしょうか?

  • C言語 空白の行(改行のみ)が入力されたらプログラムを終了する処理

    コンソールでうごくCUIプログラムを作っています。 そのとき文字列を入力してEnterキーを押すと、その文字列を格納したり何らかの処理をします。問題は何も入力せずにEnterキーを押された場合、プログラムを終了するという処理です。 どのようなソースになるのでしょうか?

  • オープンソースのhファイルをメモ帳で開くと改行されていない

    あるオープンソースのヘッダファイルを入手しました。 ただこのファイルはVisual C++ の編集画面では綺麗に改行されて表示されるのですが、メモ帳で開くと改行されないで表示されます。(但し、改行を表す↑が現れます。) メモ帳でも改行されるようにしたいのですが、良い方法はあるのでしょうか。 このままの状態でデバッグすると、”予期せぬ EOF が検出されました。”のエラーがでてしまいます。

  • C言語switch文のcase記述について

    switch文のcaseがたくさんあるため、ソースファイルとして外だししたいと思っています。 ただ、switch文そのものはきちんと記述し、caseの部分だけを外だしできればと考えています。 例 switch (a) { case 1: case 2: : :(たくさん続く) 処理A; case 100; case 101; : : (これまたたくさん続く)  処理B; } を switch (a) { A_WO_SURU_JOUKEN  /* この記述を外だししたい */ 処理A; B_WO_SURU_JOUKEN /* 同じく */ 処理B; } といった具合にしてみたいということです。 ヘッダファイルを使う、defineでの記述で可能といったものを教えていただければ幸いです。

  • Readメソッドが次の行に処理を渡すタイミング

    C#ですが、Readメソッドを使ってバイト配列を 読み込むとき、次の処理に移るタイミングが よく分かりません(ソケットからデータを受ける時)。 例えば、JAVAなどのreadLine()などは、改行や、 EOFで、次の行に移ります。 Readは、このような、区切りが無いのでよく分かり ません。 0バイトで移るのかとも思いましたが、受信バイト数 を数えると、文字数以上のバイトはいっさい受信 されていないので、送信側で、自動で0バイトを つけているようでもありません。 それでも送信側で文字を送ると、その送信単位で 次の処理に移ってくれています。 送信から次の送信までの区切りは何で認識して いるのでしょうか(区切りがない以上、受信バッファ がいっぱいになるまで、待ってもよさそうですが)。 なにか分かる人がいましたらお願いします。

  • VB6のテキスト処理 さまざまな文字コード/改行で対応

    VB6のテキスト処理で、Open InputとLine inputを使った場合に 文字コード/改行コードが SJIS/CRLFの時は正しく1行を読み込む事ができますが、改行がLFの時は正しく1行を読み取りません。 改行コードがLFもしくはCRの場合でも正しく1行を読み取る方法はあるのでしょうか? また、文字コードに関してもEUCやUTF-8,JISでも対応できる方法がありましたら教えて下さい。

専門家に質問してみよう