1. ホーム
  2. スクリプト・コラム
  3. その他

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

2022-01-16 22:37:42

質問

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 release 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 は互換性がありません。

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