1

したがって、C のいくつかの変数から constness を削除する必要があります (自分が何をしているのかはわかっています)。UNCONSTそこで、const 値に新しい値を代入できる小さなマクロ ( ) を書きました。これは、 のような型の通常の変数に対しては問題なく機能しますint。しかし、これはポインターには機能しません。そのため、マクロUNCONSTを使用してポインタが別の位置を指すようにすることはできません。コンパイラの警告が表示されます。

ここに小さなテストプログラムがありunconst.cます:

#include <stdio.h>

#define UNCONST(type, var, assign) do { \
  type* ptr = (type*)&(var); \
  *ptr = (assign); \
} while(0)

struct mystruct {
  int value;
  char *buffer;
};

int main() {
  // this works just fine when we have an int
  const struct mystruct structure;
  UNCONST(int, structure.value, 6);
  printf("structure.value = %i\n", structure.value);

  // but it doesn't when we have an char *
  char *string = "string";
  UNCONST(char *, structure.buffer, string);
  printf("structure.buffer = %s\n", structure.buffer);

  // this doesn't work either, because whole struct is const, not the pointer.
  structure.buffer = string;
  printf("structure.buffer = %s\n", structure.buffer);
}

コンパイルと実行

$ LANG=en gcc -o unconst unconst.c
unconst.c: In function ‘main’:
unconst.c:21:3: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
unconst.c:25:3: error: assignment of member ‘buffer’ in read-only object

この警告が表示されないようにマクロを最適化する方法はありますか?

4

2 に答える 2

4

問題:

const char *string1 = "string1";
UNCONST(char *, string1, string2);

これはstring1実際には const ではなく、代入できますが、const 文字の配列を指します。

実際に、やっている:

string1 = string2;

うまくコンパイルされます。

もう1つは、配列をコピーする場合です。次に、マクロを次のように記述します。

#define UNCONST(type, var) (*(type*)&(var))

など:

UNCONST(int, i) = 42;

文字の配列をコピーするには、次のようにします。

strcpy(UNCONST(char**,string1), string2);

脚注: 実際、このマクロは役に立たないと思います:

*(int*)&i = 42;

この種の操作と同じくらい面倒です。

于 2012-11-15T21:10:00.503 に答える
0

string1が(constデータへの非constポインターではなく)constポインターであると想定される場合は、次のように記述します。

char * const ptr = "foo";

また

const char * const ptr = "foo";

たぶん(私はそれをテストしていません)、ポインタを正しく宣言した場合、UCONSTマクロは期待どおりに機能します。

于 2012-11-15T21:14:37.570 に答える