質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

7回答

5785閲覧

C言語ヘッダーファイルのインクルードガードで、#defineの書き方について

maisumakun

総合スコア145121

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

2グッド

4クリップ

投稿2016/05/16 09:02

編集2016/05/17 00:50

C言語を書いていると、大量のヘッダーファイルが必要となるので、多重読み込みの混乱を避けるためにインクルードガードが必要となります。

#pragma onceという標準化されていない方法もあるのですが、移植性のあるやり方としては#ifndef#define#endifの流れとなっています。

もちろん特に問題なく使っていたのですが、あるときこんなヘッダーファイルを見つけてしまいました。

C

1/* define_only.h:自分が書いていたやり方 */ 2#ifndef DEFINE_ONLY_H_INCLUDED 3#define DEFINE_ONLY_H_INCLUDED 4 5/* ヘッダーの中身 */ 6 7#endif /* DEFINE_ONLY_H_INCLUDED */ 8 9/* define_1.h:新しく見かけたもの */ 10#ifndef DEFINE_1_H_INCLUDED 11#define DEFINE_1_H_INCLUDED 1 12 13/* ヘッダーの中身 */ 14 15#endif /* DEFINE_1_H_INCLUDED */

インクルードガードに使う記号定数に値を割り当てることで、何かしらのメリットがあるものなのでしょうか。ご存知でしたらお知らせいただければ幸いです。

(2016/05/17 9:48 追記)

見かけた場所というのが、Ruby処理系のヘッダーファイル内です。検索してもインクルードガード以外に使われていなさそうだし、ほぼ全ファイルで1が#defineされていました。

MIURA_Yasuyuki, LouiS0616👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

ベストアンサー

本題から外れますが、参考までにこういう意見もあるようです。

2016年、C言語はどう書くべきか (後編) | モダンコンパイラが#pragma onceをサポート

Wikipedia[en]: pragma once | Portability によると現在も開発されているメジャーなコンパイラの中で未対応なのはOracle Solaris Studioだけのようです。どこまで移植するかによりますが、C11をターゲットにした今風のC言語にするのであれば、標準には無い#pragma onceを使用しても問題無いかも知れません。


【追記1】

ふと気付いたのですが、ANSIになる前のC言語では、#defineで置換後のテキストが必須だったと言うことはないでしょうか? ANSI規格準拠のK&R第二版では置換後のテキストはありません(和訳本p.112の例)でしたので、ANSIの時点で書かなくてもよくなったと推測できませんでしょうか? もしK&R初版をお持ちの方がいれば、どのように書かれているのか教えて欲しいです。


【追記2】

GNU libtoolのドキュメントの中で、インクリュードガードの例で同じく1と入れているものが載っていました。
http://www.geocities.jp/fut_nis/html/libtool-ja/C-header-files.html
上のドキュメントは移植性が高いヘッダファイルの作り方に関してです。ANSI以降は問題ないはずですので、非ANSIとの互換性のためかにそのようにしているのかも知れません。

投稿2016/05/16 09:47

編集2016/05/17 09:32
raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2016/05/17 01:02

これからC/C++を書く上で、pragmatically(実用的には)それでいいかもしれませんね。 とはいえ、既存のコードを理解することも確実に欠かせないものではあります。
Chironian

2016/05/17 11:01 編集

> 【追記2】 おお、凄い。よく見つけたですね。 推奨されている通りに記述している可能性高そうですね。
guest

0

こんにちは。

記憶が定かではないのですが、大昔のCコンパイラで#define FOOのような空定義ができないものがあったような気がします。
そのような古いコンパイラの時代に慣れた人が書いたソースでしたらあり得るかも。

しかし、昔懐かしのLattice Cのアミガ用のマニュアルが有りましたが、これは空定義もサポートしているようですので記憶違いの可能性もあります。(43ページ辺り)

投稿2016/05/16 10:26

編集2016/05/16 10:27
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2016/05/17 09:22

「昔は…」説に一票。証拠は無いですけど。
guest

0

その定義に意味があるかないか本当のところは、ソースを検索するしかないと思います。
どこかのソースで、

C

1#if DEFINE_1_H_INCLUDED==1 2処理 3#endif

とかやっているかもしれません。
また別のヘッダーファイルでは、

C

1#define DEFINE_1_H_INCLUDED 2

と定義しているところがあるかもしれません。
ここで一般的な回答を求めても真相は質問者様のソースにしかわかりません。
*.h と *.c を対象に、全ファイル検索をしてみることをお勧めします。
その結果、何も出てこないのであれば、やっぱり意味のないコードだったと言えるのですから。

投稿2016/05/17 00:27

ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2016/05/17 00:54

ということで、当該のファイルについて情報を追記しました。
ttyp03

2016/05/17 01:45

こちらでも確認してみましたが、意味のある使い方をしているところはなさそうですね。 値無しの#defineもあるので言語的な制約はないものとして、作者なりの何か将来を見越したコードなのかもしれません。
guest

0

定義済みか未定義かで判断する場合、複数条件が面倒になるので、その対策として数値を使う場合があったと思います。#ifdefがネストすると読みにくくなりますから。

INCLUDE_A_HとINCLUDE_B_Hの両方が定義されていることを条件にする場合に、単に定義するのではなく1として定義しておいて、INCLUDE_A_H+INCLUDE_B_Hが2と等しいことを条件として使うわけです。

いまなら、defined(INCLUDE_A_H)&&defined(INCLUDE_B_H)でてきるのですが。

投稿2016/05/20 02:43

m-take

総合スコア249

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ほとんど回答されていると思いますが。

あまり意味無いと思います。

パターン1:
#define で マクロ定義や定数定義のように

#define TEST_N (100)

と後ろに何も書かないと違和感があるためつけた可能性。( 書いた人による。 )

パターン2:
後で定数として何かしらの処理で使うため。

パターン3:
消し忘れ。 "#define ABC 1" をコピペして、 ABCの部分を書き換えたが、割り当てられる値 ( ここでは 1 ) を消し忘れたため。

パターン4:
書いた人が間違って覚えている。(理解している。)

投稿2016/05/16 09:55

BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

単に「値を何も割り当てずに定義だけするのが気持ち悪いから」みたいな個人的好みを持ってる人が1を割り当てて定義しました…というだけのような気がします(つまりそれ自体に何か特別なトリックがあるとかいう話しではないと思います)

投稿2016/05/16 09:36

HiroshiWatanabe

総合スコア2160

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

PineMatsu

2016/05/16 09:42

「値なしの定義文が気持ち悪い」と本当に思ってるのなら、それはC言語の仕様を理解していないということで、それはそれで認識を変えて貰う必要がありますよね。
HiroshiWatanabe

2016/05/19 00:37

すみませんが記載スタイルの好みの問題がどうして仕様理解の話しに発展するのかがよくわかりません。if の { を同じ行に書いても改行してから書いても仕様を理解していないという話しにはならないでしょうし if の処理が単行でもかならず { } を省略せずに記述するのが好みですと言っても仕様を理解していないとは言われない気がしますが、なぜ define で空定義する記述が好みじゃないと仕様理解していない事になるのでしょうか…? ちなみに私は空定義使ってますので私の好みだという話しでは無いんですが(笑)ちょっと気になったので…後学のためにもう少し解説して頂けるとありがたいです。
PineMatsu

2016/05/20 08:35

言い方がまずかったかな。仕様は理解しているかもしれませんからね。 言いたかったのは、「気持ち悪い」ということから「1」を書くというのは、「感情」からそう決めているので、どうなんだろうなということです。自分の書くコードは空文定義は行わないという「スタイルを通す」のならOKだと思います。(意識の問題です) ブロックif文のかっこを改行して書くか書かないかというのはどちらも許可されているので、「スタイルが統一」されていればOKだと思います。 つまり、スタイル統一という意識からそう書いているのならいいと思いますが、好き嫌いの感情から決めるというのは、プログラミングでは極力廃すべき事ではないかと思うのです。 C言語の仕様として空文定義が許されているのならそれは無条件に受け入れるべきで、気持ち悪いとかという感情から書き方を決めるのはちょっとおかしいんじゃない?ということです。 私も、if文のかっこや空白の入れ方など人によってまちまちなので、他人が書いたソースを読むと違和感を覚えることはあります。でも、それはその人がそういうスタイルなんだなと受け入れるしか無いと思っています。でも複数人で1つのプロジェクトをやる場合は、予めある程度のスタイルを決めておいたほうがいいとは思います。ただし、ガチガチにしてしまうとやりにくくなるので柔軟な感じにしたほうがいいでしょうね。
guest

0

#ifndef XXXXがXXXXが未定義なら以下を展開するという意味なので、XXXXに数値や何かを割り当てる意味は無いと思いますが、このヘッダーファイルの中やインクルードしているソースでXXXXの値を使っている場合は意味が出てくるかも。
ただ、その数値を何かの間違いだと思って消したり、値を変えてしまうと参照している箇所でおかしなことになる可能性があるので、こういう通常の使い方から外れたやり方は好ましくはないと思います。

投稿2016/05/16 09:09

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問