ビルドエラーC2106 について

解決


ガムラン  2011-05-16 14:39:37  No: 72613  IP: 192.*.*.*

お世話になっております。

前回、USBの質問をさせて頂き、回答頂いた内容から、USB Viewのソースコードを流用することで、自分の望むディスクリプタが取得できそうだということがわかりました。

そこで、USB Viewのソースコードを自分の開発中のプログラムへ移植中に、下記のような問題が発生してしまっています。
原因がわからず、どこから調べ始めれば良いのかもわからないので、アドバイスを頂ければと思います。

・環境
OS        WindwsXP SP3
開発環境  Visual Studio 2005 SP1
使用言語  VC++ MFC

・事象
「C2106 左のオペランドが、左辺値になっていません。」が発生してしまう。

・内容
USB Viewのソースを流用し、自分のプログラムへ移植したところ、ビルドエラーC2106が発生した。
下記、ホームページを元にUSB Viewのソースコードをプロジェクトにし、ビルドしたものでは、問題無くビルドできている。

http://blogs.dion.ne.jp/onechu_blog/archives/8701402.html

上記のエラー以外にビルドエラーは発生していない。

・確認内容
自分のプログラムの設定を全て上記の設定に合わせてみたが、解決せず。
(インクルードの設定、リンカの設定)

よろしくお願いします。

編集 削除
tetrapod  2011-05-16 14:55:13  No: 72614  IP: 192.*.*.*

1=1; // に対して C2106 が発生
if (-1=index) // に対して C2106 が発生
代入式の左辺が変数でないってこと(後者は -1==index と書きたかったらしい)

単なるバグ、ないしはタイプミスの可能性大。
当該エラーの前後(特に前)を虚心坦懐に先入観なく見直すべし。

編集 削除
ガムラン  2011-05-16 16:21:37  No: 72615  IP: 192.*.*.*

tetrapod さん
返信ありがとうございます。

エラーが発生しているのは下記の一行です。

(PUCHAR)commonDesc += commonDesc->bLength;

commonDesc は PUSB_COMMON_DESCRIPTOR 構造体で

typedef struct _USB_COMMON_DESCRIPTOR {
    UCHAR bLength;
    UCHAR bDescriptorType;
} USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR;

と定義されています。

自分自身で、サンプルプログラムを作成し、

PUSB_COMMON_DESCRIPTOR PCD;
PCD->bDescriptorType = 9;
PCD->bLength = 4;
(PUCHAR)PCD += PCD->bLength;

としてみましたが、(PUCHAR)PCD += PCD->bLength;  で同じエラーが出ます。

見直しは今、行なっている最中です。

編集 削除
tetrapod  2011-05-16 18:13:38  No: 72616  IP: 192.*.*.*

それは USBVIEW のソースコードのバグ。要修正。

(PUCHAR)PCD += PCD->bLength; の左辺はキャスト式=右辺値なので、
言語規格書的にはこのコードがコンパイルできてはならない (C/C++ とも)

Microsoft 拡張機能有効 -Ze 時 C ソースコードに限定して
キャスト式を左辺値として認める動作をしているので
display.c のように C ソースコードであればコンパイルに通ってしまうのだ。

ぱっと見で USBVIEW のソースコードにはそういうコードが山盛りなので、
かなりの量の修正が必要だろう。

編集 削除
ガムラン  2011-05-17 10:06:51  No: 72617  IP: 192.*.*.*

tetrapod さん
ありがとうございます。

問題なくビルドできるプロジェクトにも、コンパイルオプションで/Zeを指定するようなことはしていません。
逆に、ビルドエラーが起きているプロジェクトに/Zeを指定してみましたが、結果は変わらずでした。

(PUCHAR)PCD += PCD->bLength;

は、単純にポインタを移動させているだけですよね?
これを問題が起きないように修正するには、どうすれいいのでしょうか?

PUCHAR puchr;
puchr = (PUCHAR)PCD;
puchr = puchr + PCD->bLength;
PCD = puchr;

のように単純に書き方を変えれば良いような気もするのですが、
見当がつきません。(上記も4行目でエラー・・・)
自分でも調べてみます。

編集 削除
ガムラン  2011-05-17 10:34:46  No: 72618  IP: 192.*.*.*

あほだ・・・。
最後もキャストしないとダメですね。

PUCHAR puchr;
puchr = (PUCHAR)PCD;
puchr = puchr + PCD->bLength;
PCD = (PUSB_COMMON_DESCRIPTOR)puchr;

これでビルドは通りました。
ビルドが通っているプロジェクトを同じものに変更して、実行し、値の確認をしましたが、変更前と同じだったのでこれで大丈夫だと思うのですが・・・。

編集 削除
tetrapod  2011-05-17 21:52:13  No: 72619  IP: 192.*.*.*

よく読むべし

C ソースコード + (暗黙の) -Ze 指定時には OK と俺は書いた。
明記せずともわかるだろうと思って省略したのは下記。
C++ ソースコード だと -Ze/-Za 両方でエラー
C ソースコード + -Za 指定時にはエラー

ガムラン氏は MFC と書いているので、想像するに(妄想ともいうが)
※ C++ ソース中に当該「キャスト式を左辺値にする」コードを書いた
のではないか、と言う判断を、俺は 5/16 時点で既にした上での発言となっている。

コード修正内容はそれでいいだろう。
(俺ならまったく違う方式に書き直すだろうが)
実行時でないとわからない可変個数可変内容構造体っつのは、
もっとも C++ に適合しない *らしくない処理* になるので
どう書いてもかっこよくならないんで・・・

編集 削除
ガムラン  2011-05-20 11:35:32  No: 72620  IP: 192.*.*.*

tetrapodさん

返信ありがとうございます。
解決と致します。

編集 削除