1. ホーム
  2. c++

[解決済み】エラー: lvalue は単項演算子として必要です。

2022-03-11 01:53:41

質問

コンパイル中(Linux Server リリース 6.1使用時)

strftime(AppTime, sizeof(AppTime),"%Y/%m/%d %T", localtime(&((long)u32_Time)));

エラー発生 "error: lvalue required as unary '&' operand"

しかし、同じコードが Red Hat Enterprise Linux AS リリース 3 で正常にコンパイルされました。

なぜそうなのでしょうか?どうすれば修正できますか?

どのように解決するのですか?

アドレス演算子 & は、アドレスを取得するための変数を必要とします。キャストの結果 (long)u32_Time は、必ずしもメモリ上に存在しないテンポラリであるため、取得可能なアドレスがありません。そのため、このコードがどこかでコンパイルされたことがあるとすれば、それは非標準のコンパイラ拡張である。

規格では、§5.3.1,3が要求しています。

単項演算子 & の結果は、オペランドへのポインタである。オペランドは、lvalue [...]でなければならない。

これを修正する方法 std::localtime へのポインタを期待します。 std::time_t ということで、それを提供するのがベストです。説明やさらなるコードは提供されていませんので、私は次のように推測することができます。 u32_Time は4バイトの符号なし算術型で、何らかの方法で時間を表現することになっています。それがどのように正しく変換され std::time_t は、コンパイラが後者をどのように実装しているか、さらにその値をどのように取得したかに依存します。単純にCキャストを適用すると ではなく へのキャストは移植可能であり long はさらにポータビリティに欠ける。
もし、もし、もし その std::time_t 現在お使いのプラットフォームで と同じ表現で、符号なし32ビット型でもあります。 u32_Time を使用すれば十分でしょう。

 localtime(reinterpret_cast<std::time_t*>(&u32_Time));

よりポータブルなのは、最初に正しいデータ型に値を格納することでしょう。

 std::time_t time = u32_Time;
 localtime(&time);

このようにすると、以下のような場合に必要な警告やエラーが表示されます。 time_t であり、その型は u32_Time は互換性がありません。

なぜなら、このコードを他のプラットフォームに移植しなければならなくなったとき、その厄介なキャストを簡単に見つける手段がなくなってしまうからです。