2016-10-27 3 views
6

この有効なインライン関数の使用法はありますか?

inline float SecondsToMinutes(float seconds) 
{ 
    return seconds/60.0; 
} 
inline float MinutesToHours(float minutes) 
{ 
    return minutes/60.0; 
} 
inline float HoursToDays(float minutes) 
{ 
    return minutes/24.0; 
} 
inline float SeconndsToHours(float seconds) 
{ 
    return MinutesToHours(SecondsToMinutes(seconds)); 
} 
inline float MinutesToDays(float minutes) 
{ 
    return HoursToDays(MinutesToHours(minutes)); 
} 
inline float SeconndsDays(float seconds) 
{ 
    return MinutesToDays(SecondsToMinutes(seconds)); 
} 

はインラインのこの有効な使用です(SecondsToMinutesとMinutesToHoursが互いのカーボンコピーであるという事実を気にしない)のは、私はこのコードを持っているとしましょうか?それは理にかなっていますか?これはいい練習ですか?私が正しくリコール場合は結局のところ、インラインは

return MinutesToDays(SecondsToMinutes(seconds)) 

return seconds/60.0/60.0/24.0 

右に同等でなければなりませんので、関数呼び出しは、関数本体によって置き換えられていることを意味しますか?

これにはマクロを使用する方がよいでしょうか?

#define EXCHANGE_SEC_MIN(x) (x/60.0) 
#define EXCHANGE_MIN_H(x) (x/60.0) 
#define EXCHANGE_H_D(x) (x/24.0) 
#define EXCHANGE_SEC_H(x) (EXCHANGE_MIN_H(EXCHANGE_SEC_MIN(x))) 
#define EXCHANGE_MIN_D(x) (EXCHANGE_H_D(EXCHANGE_MIN_H(x))) 
#define EXCHANGE_SEC_D(x) (EXCHANGE_MIN_D(EXCHANGE_SEC_MIN(x))) 

これはどちらが良い方法ですか?またはどちらもですか?私は他の人にこれについてセントをしたいと思います。

+7

マクロほとんど*必ず* :-) – paxdiablo

+2

間違った方法ですあなたのマクロも間違っています: 'EXCHANGE_SEC_MIN(a + b)'のように使うとどうなりますか? – mch

+0

*マクロはほとんど常に間違った方法です*言い換えれば、マクロ(この場合は関数ですが、インラインであってもなくても)がマクロを避けることを好みます。 – Leon

答えて

6

これは有効なインライン使用ですか?それは理にかなっていますか?

まあ、ええ、いいえ。

この時点では何も傷つけることはありませんが、どちらかと思われることはしません。 excellent post about inline deft_codeで

正しく言う:

あなたが 機能を考えるコンパイラへinlineヒントがインライン化されるべきであると言われています。これは1998年にも当てはまるかもしれませんが、その後十年後には というコンパイラはそのようなヒントを必要としません。人間のことは言うまでもなく はコードを最適化するときに間違っているので、ほとんどのコンパイラ は「ヒント」を無視しています。

コンパイラがあなたのヒントを聞く可能性は実質的に0です。コードをインライン化するのに適していると思われる場合は、それ自体が行います。

inline現在では、複数のコンパイル単位で複数の定義が可能なため、ほとんどの場合リンカーとして使用されます。

あなたのコードは、可能な限り高速であり、あなたがC++ 11あなたはconstexprを使用する必要がありますへのアクセスを持っていることを確認したい場合:

constexpr float SecondsToMinutes(float seconds) 
{ 
    return seconds/60.0; 
} 
//etc.. 
+0

'constexpr'は単なるヒントに過ぎないことに注意してください。定数式(例えば、テンプレートの非型引数)で使用されていない限り、コンパイル時に評価する必要はありません。コンパイル時にその引数が分からない場合、コンパイル時に評価することはできません。また、C++ 98コンパイラは、コンパイル時に既知の引数に対しても定数フォールディングを実行できます。 – Oktalist

+0

@Oktalist非常に真実ですが、この場合、 'inline'キーワードよりもコンパイラによって使用される可能性が高くなります。 –

7

これは有効なインライン使用ですか?それは理にかなっていますか?これはいいですか 練習ですか?結局のところ、私が正しく思い出すと、インラインとは関数 の呼び出しが関数本体に置き換えられていることを意味するので、

です。あなたはそれを常に見やすくすることができます。

return seconds/60.0/60.0/24.0 

はい、そうです。あるいはそうするべきです。 inlineはほんのヒントに過ぎず、コンパイルによって他の点が決まる可能性があります。しかし、そのようなライナーの場合、コンパイラはインライン展開します。

マクロ?どうして?関数で行うことができれば、なぜマクロを使うのですか?

+0

あなたの答えをありがとう:)私は彼らが何のために良いか知っているので、私は将来的にインライン関数を使用するようになるでしょう。 –

+1

'inline'はこのような小さな関数では非常に便利ですが、大きな関数ではこれを行う際には注意が必要です。コードの膨張が悪いあぶない!コンパイラは、浮動小数点演算のため、コードを1つの除算に減らしません!互換性の問題を気にしない場合は、フラグ '-ffast-math'を有効にしてください。 [godbolt](https://godbolt.org/g/7NBXMy)の有無にかかわらず、違いを参照してください。 – Asu

3

inlineは、ではありません。は、関数呼び出しが関数本体に置き換えられていることを意味します。少なくとも過去15年間は、オプティマイザは開発者からの注文を超えており、inlineを指定したかどうかに関係なくインライン展開を実行することになりました。

inlineが実際に意味は、「この機能は、複数回定義することができる、とリンカがそれを整理し、最後に最大で単一の定義を維持する必要があります。私は、すべての定義が同一であることを保証する責任です」。

あなたは本当に、は本当にを自分で(呼び出し側の内部関数の身体の実際の挿入)をインライン化強制する場合は、そのよう__attribute__((always_inline))としてコンパイラ固有の拡張機能を使用する必要があります。

このヘッダーは最終的にいくつかの翻訳単位に含まれるため、定義が複製されるため、通常、関数がヘッダーに定義されている場合は、inlineが必要です。そのため、あなたのコードがヘッダーの内部にあると仮定すると、これはinlineの有効な使い方です。

0

インライン関数の定義は、使用時にコンパイラに表示されるものとします(たとえば、各コンパイル単位で必要に応じて#includedというヘッダーファイルに記述されています)。

ただし、inlineはコンパイラのヒントに過ぎません。標準では、コンパイラはそのヒントを無視し、関数をインライン化することはできません。コンパイラが関数をインライン化しない基準は、コンパイラによって大きく異なります。

マクロは代替ですが、プログラムの範囲を尊重しないなど、他の懸念事項もあります。意図的でも偶発的にもマクロを書くのは簡単です。したがって、インライン関数はしばしば好ましいと考えられます。

関連する問題