リテラル文字列は適切な const char[] 型を持つ
更新 : 2007 年 11 月
リテラル文字列は、const char [] 型を持ち、読み取り専用のメモリ セクションに置かれるようになりました。今後、メモリを変更するとアクセス違反になります。前のバージョンで /GF を使用してコンパイルされたコードもアクセス違反になります。
次のコード例は、Visual Studio .NET ではコンパイルされ、実行されますが、Visual Studio .NET 2003 では実行時にエラーになります。
// bc_string_literals_have_proper_type_of_const_char.cpp
// compile with: /c
void f(char *c) {
c[0] = 'Q'; // Now gives run-time access violation
}
int main() {
f("TEST");
}
さらに、次の例のようにコードの実行時の動作も変更されました。
// bc_string_literals_have_proper_type_of_const_char2.cpp
#include "stdio.h"
void f(const char *) { // called in Visual Studio .NET 2003
printf_s("in f(const char *)\n");
}
void f(char *) { // called in Visual Studio .NET
printf_s("in f(char *)\n");
}
int main() {
f("TEST");
}
このエラーを解決するには、変更される関数にリテラル文字列を渡さないでください。
次のように関数がオーバーロードされる場合には、現在のバージョンの Visual C++ でも前のバージョンの Visual C++ でもコードは有効になります。
リテラル文字列を const char* に明示的にキャストする。
スタックまたはヒープの変数を定義する。
次のコードは、Visual Studio .NET 2003 と Visual Studio .NET の両方のバージョンの Visual C++ で有効となり、アクセス違反にもなりません。
// bc_string_literals_have_proper_type_of_const_char3.cpp
#include <stdio.h>
void f(const char *psz) {
printf_s("const version\n");
}
void f(char *psz) {
printf_s("version where we modify it\n");
psz[0] = 'x';
}
int main() {
char myStr[] = "TEST";
f((const char*)"TEST");
f(myStr);
}