2017-05-08 6 views
2

「Cのポインタの理解と使用」という本を読んでいます。 は、110ページ、それはこれらの行だった:いくつかのGCCコンパイラは、定数charポインタをどのように変更できますか?

を...しかし、そのようなGCCなどいくつかのコンパイラで、文字列リテラルの変更が可能です。

char *tabheader = "Sound"; 
    *tabheader = 'L'; 
    printf("%s\n", tabheader); //Displays "Lound" 

それが経つと、この変数を変更することから防ぐことができますconst char *tabheaderの使用法を説明します。次の例を考えてみましょう。

私は現在Cloud 9/Ubuntuを使用しています。 GCCを使ってこのコードをコンパイルして実行しました。期待通りにsegmentation faultエラーが発生しました。

私は本の中のこれらのステートメントに非常に混乱しています。 すべてのこの時間は、声明char *tabheader = "Sound";の私の理解は今const char *tabHeader = "Sound";と同じですが、この本はそれが

たGCCコンパイラに依存していると言っている私の質問はこれです:このコードを実行することを可能にするGCCコンパイラ? これについてあなたの意見は何ですか? これも未定義の動作に属していますか?

+3

この本は明らかに間違っています。可能かもしれませんが、未定義の動作が発生します。あなたが実証したように。 –

+3

文字列リテラルは変更できません。ただし、変更の結果は未定義の動作です。 – BLUEPIXY

+1

GCCの古いバージョンには、これを可能にする '-fwritable-strings'オプションがありました。それはGCC 4.0で削除されました。 – Barmar

答えて

4

メモリの保護された部分に文字列リテラルを格納しないシステムでは動作します。たとえば、GCCのAVRポートは文字列リテラルをRAMに格納し、すべてのRAMは書き込み可能であるため、おそらくそれらに書き込むことができます。一般的に、文字列リテラルへの書き込みは未定義の動作ですので、実行しないでください。

は、あなたがこの2行の違いについて混乱した言及:

char *tabheader = "Sound"; 
const char *tabHeader = "Sound"; 

主な違いは、const修飾子を指定して、コンパイラはコンパイル時に知っていることであるあなたは、文字列に書き込むことはできません、それがするので、実行時に未定義の動作ではなく、コンパイル時にエラーを出します。

4

これは、コンパイル時に-fwritable-stringsオプションを使用すると、4.0より前のGCCのバージョンで動作します。このオプションは4.0で削除されました。

1

gccには多くのモードと互換性があります。当初(1970年代)のCには、constタイプがなく、確かに文字列リテラルが一定であるという概念はありませんでした。当時、バッファ初期化として文字列リテラルを使用するのは、時折の(ただしまれではない)練習でした。

文字列リテラルが暗黙の定数になるまでの進化は、初期の動作に依存する古代コードの維持に伴う痛みを引き起こしました。 Gccの考え方は、明らかにコンパイラフラグで古い動作を可能にします。例えば、GCC 6.3.1 20161221ためman gcc(レッドハット6.3.1-1)から、-std上のセクションでは、(部分的に)である:

-std= 
     Determine the language standard. This option is currently only 
     supported when compiling C or C++. 

     The compiler can accept several base standards, such as c90 or 
     c++98, and GNU dialects of those standards, such as gnu90 or 
     gnu++98. When a base standard is specified, the compiler accepts 
     all programs following that standard plus those using GNU 
     extensions that do not contradict it. For example, -std=c90 turns 
     off certain features of GCC that are incompatible with ISO C90, 
     such as the "asm" and "typeof" keywords, but not other GNU 
     extensions that do not have a meaning in ISO C90, such as omitting 
     the middle term of a "?:" expression. On the other hand, when a GNU 
     dialect of a standard is specified, all features supported by the 
     compiler are enabled, even when those features change the meaning 
     of the base standard. As a result, some strict-conforming programs 
     may be rejected. The particular standard is used by -Wpedantic to 
     identify which features are GNU extensions given that version of 
     the standard. For example -std=gnu90 -Wpedantic warns about C++ 
     style // comments, while -std=gnu99 -Wpedantic does not. 

     A value for this option must be provided; possible values are 

     c90 
     c89 
     iso9899:1990 
      Support all ISO C90 programs (certain GNU extensions that 
      conflict with ISO C90 are disabled). Same as -ansi for C code. 

     iso9899:199409 
      ISO C90 as modified in amendment 1. 

     c99 
     c9x 
     iso9899:1999 
     iso9899:199x 
      ISO C99. This standard is substantially completely supported, 
      modulo bugs and floating-point issues (mainly but not entirely 
      relating to optional C99 features from Annexes F and G). See 
      <http://gcc.gnu.org/c99status.html> for more information. The 
      names c9x and iso9899:199x are deprecated. 

     c11 
     c1x 
     iso9899:2011 
      ISO C11, the 2011 revision of the ISO C standard. This 
      standard is substantially completely supported, modulo bugs, 
      floating-point issues (mainly but not entirely relating to 
      optional C11 features from Annexes F and G) and the optional 
      Annexes K (Bounds-checking interfaces) and L (Analyzability). 
      The name c1x is deprecated. 

     gnu90 
     gnu89 
      GNU dialect of ISO C90 (including some C99 features). 

     gnu99 
     gnu9x 
      GNU dialect of ISO C99. The name gnu9x is deprecated. 

     gnu11 
     gnu1x 
      GNU dialect of ISO C11. This is the default for C code. The 
      name gnu1x is deprecated. 

     c++98 
     c++03 
      The 1998 ISO C++ standard plus the 2003 technical corrigendum 
      and some additional defect reports. Same as -ansi for C++ code. 

     gnu++98 
     gnu++03 
      GNU dialect of -std=c++98. 

     c++11 
     c++0x 
      The 2011 ISO C++ standard plus amendments. The name c++0x is 
      deprecated. 

     gnu++11 
     gnu++0x 
      GNU dialect of -std=c++11. The name gnu++0x is deprecated. 

     c++14 
     c++1y 
      The 2014 ISO C++ standard plus amendments. The name c++1y is 
      deprecated. 
... 

注受諾又は拒絶または制御する他のコンパイラフラグがあることR & R関数ヘッダおよび類似の態様の代替処理。

関連する問題