私はAndroidで使用するライブラリを持っていますが、問題はAndroid固有の問題ではないと確信しています。 このライブラリには、logcatに出力する一連のエラーコードが含まれており、すべてが定数文字列で構成されています。ライブラリの.soファイルの `const char *`ストレージの奇妙な動作
...
if(...){ALOGE("Error in parameter XXXXXX");}
if(...){ALOGE("Error in parameter YYYYYY");}
if(...){ALOGE("Error in parameter ZZZZZZ");}
...
今日私は自分の.rodataセクション(約16kB)に大量のデータがあることに気付きました。だから私はstrings mylib.so
を実行し、それらの文字列の束を得た。
Error in parameter XXXXXX
Error in parameter YYYYYY
Error in parameter ZZZZZZ
Iしかし、私は2つの部分で文字列を分割場合(これらのコードはめったに使用されているので、問題ないはずですが)印刷の小さな余分なコストで、私はスペースで多くを救うことができること。その後、コンパイラはジョブを実行し、共通部分を1つの文字列にグループ化する必要があります。コンパイラには、文字列削除の最適化ステップ(CLANGとGCC)が重複しているためです。
私はそれをこのように行った:()私は定義(これは簡単なテストだった使用する必要があります知っている、私はこれらの多くを持っていますが、それらはすべて、このようなパターンを持っている)
...
if(...){ALOGE("Error in parameter %s","XXXXXX");}
if(...){ALOGE("Error in parameter %s","YYYYYY");}
if(...){ALOGE("Error in parameter %s","ZZZZZZ");}
...
何私が見つけたのは:
- ライブラリーは正確に同じサイズです。
.rodata
は現在かなり小さくなりますが、.text
はほぼ同じ量だけ増加しています。 (数バイトの違いのみ) strings
コマンドは今度は"Error in parameter %s"
文字列と分離された部分だけを出力します。したがって、文字列のマージは行われません。- だから
..私は32ビット、64-ビットなどでコンパイルした場合には関係していないよう、ここで何が起こっているの?どうすれば修正できますか?どんな指導?コンパイラは何をしていますか? おかげ
エクストラデータ:
- コンパイラCLANG 4.9(4.8は、同じ結果を行います)。
- フラグ:-Os -fexceptions -std = C++ 11 -fvisivility =隠さ
EDIT:
私はGCCと同じ結果にOnline GCC
を使用してオンラインサンプルテストを作成分割:
#include <stdio.h>
int main()
{
int a = rand()%7;
switch(a){
case 0: printf("Hello, %s!\n","Anna"); break;
case 1: printf("Hello, %s!\n","Bob"); break;
case 2: printf("Hello, %s!\n","Clark"); break;
case 3: printf("Hello, %s!\n","Danniel"); break;
case 4: printf("Hello, %s!\n","Edison"); break;
case 5: printf("Hello, %s!\n","Foo"); break;
case 6: printf("Hello, %s!\n","Garret"); break;
}
return 0;
}
NonSp点灯:
でコンパイル#include <stdio.h>
int main()
{
int a = rand()%7;
switch(a){
case 0: printf("Hello, Anna!\n"); break;
case 1: printf("Hello, Bob!\n"); break;
case 2: printf("Hello, Clark!\n"); break;
case 3: printf("Hello, Danniel!\n"); break;
case 4: printf("Hello, Edison!\n"); break;
case 5: printf("Hello, Foo!\n"); break;
case 6: printf("Hello, Garret!\n"); break;
}
return 0;
}
:
gcc -Os -o main main.c
gcc -Os -o main2 main2.c
サイズ:
-rwxr-xr-x 1 20446 20446 8560 Nov 16 11:43 main
-rw-r--r-- 1 20446 20446 478 Nov 16 11:41 main.c
-rwxr-xr-x 1 20446 20446 8560 Nov 16 11:42 main2
-rw-r--r-- 1 20446 20446 443 Nov 16 11:39 main2.c
文字列:
strings main2 | grep "Hello"
Hello, Anna!
Hello, Bob!
Hello, Clark!
Hello, Danniel!
Hello, Edison!
Hello, Foo!
Hello, Garret!
strings main | grep "Hello"
Hello, %s!
コード「.text」がコード – Danh
に使用されていますどのコンパイラを使用していますか?このCコードかC++コードですか?どのような最適化設定を使用していますか? –
これはC++であり、フラグは本当に特別なものではありません。ただ-Oです。私が正しく覚えていればコンパイルは4.9です。(ndk r13b) – DarkZeros