こんにちは。
C言語で以下のコードを書きました。
C
1int main(){ 2 int a=4; 3 printf("%ls\n", &a); 4 printf("%d\n", a); 5 return 0; 6}
実行結果は
4
でした。
つまり
printf("%ls\n", &a);
の結果が表示されません。
コンパイル環境は
gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3.2)
です。
何が悪いのでしょうか?
おわかりの方お教えください。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/05/05 02:32
回答6件
0
printf("%ls\n", &a);
マルチバイト文字として変数aの内容を表示させようということになりますが、これでそもそも良いのですか?また、これでいいのであればどのような表示を求めているのですか?
投稿2018/05/04 13:18
総合スコア4830
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
つprintf("%ls\n", &a); → printf("%p\n", &a);
投稿2018/05/04 13:11
総合スコア5737
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
フォーマット指示子%ls
はwchar_t *
型の文字列(NULLターミナルでなければならない)を表示する物で、wchar_t *
型の文字列を期待し、wchar_t *
型の文字列が与えられることを前提で動作します。しかし、対応する引数の&a
はint *
型であり、wchar_t *
とは型が一致しません。printf
ではフォーマットで指定した形式が期待する型と対応する引数の型が一致しない場合、その動作は未定義です。Cにおいて未定義な動作とは「何が起こるのかわからない。コード全体の内容、OSやコンパイラなどの実行環境、コンパイルのオプション、および、実行タイミング等によって、全く別の何かを表示したり、エラーになってプログラムが終了したり、何も起きなかったりと、様々な現象が発生する可能性がある」というものです。そのため、何も表示されなかったとしても、バグでもなでもなく、Cの仕様通りの動作になります。
以下、蛇足です。
さて、このコードですが、Windows環境でコンパイルしたり、Ubuntu環境でもint a = 4;
の前後にint x = 0;
等があるととASCII 4(ASCII制御文字4, EOT, 伝送終了, U+0004)が表示される場合があります。
- Windowsでは
wchar_t
がUTF-16LE(UCS-2)であり、また、リトルエンディアンであるため、int型の4は U+0004 U+0000 という文字列と見なせる。 - Ubuntu(x86_64)では
wachr_t
がUTF-32LE(UCS-4)であり、また、リトルエンディアンであるため、int型の4の前後にint型の0があると、スタック上の並びとして U+0004 U+0000 という文字列と見なせるようなメモリ配置になる場合がある。
では、何も表示されない今回の現象はなんなのでしょうか?考えられるのは、最適化によってa
がスタックに積まれず、レジストリ上でのみ処理されたということです。もうひとつ考えられるのは、スタック外のメモリ領域へアクセスがあったため、強制的に停止させられたというということです。今回のコードは一種のセキュリティーホールになっているため、glibcのprintf
にそういう仕組みがあってもいいような気がしないでもないです。ただ、それなら、プログラムの強制終了の方があり得そうですが、それはそれでDOS攻撃の起点とされると言うことで何もしないという選択になっているのかも知れません。逆アセンブリして追えばもう少し詳しくわかるかも知れませんが、いずれにしても「何が起こるかわからない」未定義の動作としては正しいため、気にしても仕方が無いのかも知れません。
投稿2018/05/04 16:07
総合スコア21735
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
%ls
で何が出力されることを期待していますか?
投稿2018/05/04 13:24
総合スコア16614
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
投稿2018/05/04 13:37
総合スコア1195
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/05/05 04:36 編集
2018/05/05 04:38
2018/05/05 04:40
0
wchar_tって環境依存でucs2だったりucs4だったりするんだよね
c
1#include <stdio.h> 2#include <stdint.h> 3 4int main(){ 5 int64_t a=0x38; 6 printf("[%ls]\n", &a); 7 printf("[%ld]\n", a); 8 return 0; 9}
投稿2018/05/04 13:30
総合スコア15147
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。