例を挙げて説明しますが、これは私が直面している問題を実証すると思います。これは、現実的にはほど遠い、簡単なテストプログラムであるが、それはあなたが 実際にマクロを展開する関数でvalgrindを使用する方法
==25304== Memcheck, a memory error detector
==25304== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25304== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==25304== Command: ./macro-valgrind
==25304==
==25304== Conditional jump or move depends on uninitialised value(s)
==25304== at 0x40056F: my_test_function (macro-valgrind.c:30)
==25304== by 0x400597: main (macro-valgrind.c:41)
==25304== Uninitialised value was created by a stack allocation
==25304== at 0x40057F: main (macro-valgrind.c:37)
==25304==
==25304== Conditional jump or move depends on uninitialised value(s)
==25304== at 0x40053A: my_float_function (macro-valgrind.c:23)
==25304== by 0x4005BC: main (macro-valgrind.c:43)
==25304== Uninitialised value was created by a stack allocation
==25304== at 0x40057F: main (macro-valgrind.c:37)
==25304==
==25304== Conditional jump or move depends on uninitialised value(s)
==25304== at 0x400547: my_float_function (macro-valgrind.c:23)
==25304== by 0x4005BC: main (macro-valgrind.c:43)
==25304== Uninitialised value was created by a stack allocation
==25304== at 0x40057F: main (macro-valgrind.c:37)
==25304==
==25304==
==25304== HEAP SUMMARY:
==25304== in use at exit: 0 bytes in 0 blocks
==25304== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==25304==
==25304== All heap blocks were freed -- no leaks are possible
==25304==
==25304== For counts of detected and suppressed errors, rerun with: -v
==25304== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
のような出力に含まが表示されます。このコードをコンパイルして
valgrind --show-origins=yes ./compiled-program
を使用する場合、問題は非常によく
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 struct first {
5 int i_value;
6 };
7
8 struct second {
9 float f_value;
10 };
11
12 #define DEFINE_FUNCTION(type, struct_name, field_name) \
13 void my_ ## type ## _function(struct struct_name *object, type value) \
14 { \
15 /* Deliberately read an uninitialized value to make valgrind */ \
16 /* report the issue */ \
17 if (object->field_name == -1) \
18 return; \
19 object->field_name = value; \
20 }
21
22 DEFINE_FUNCTION(int, first, i_value);
23 DEFINE_FUNCTION(float, second, f_value);
24
25 void
26 my_test_function(struct first *object, int value)
27 {
28 /* Deliberately read an uninitialized value to make valgrind */
29 /* report the issue */
30 if (object->i_value == -1)
31 return;
32 object->i_value = value;
33 }
34
35 int
36 main(void)
37 {
38 struct first frst;
39 struct second scnd;
40
41 my_test_function(&frst, -5);
42 my_int_function(&frst, -2);
43 my_float_function(&scnd, 3.0);
44
45 return 0;
46 }
を示してい
上記のvalgrind出力からわかるように、最初に読み込まれた初期化されていない読み取りはmy_test_function()
関数からのもので、問題が発生しました。このようにすれば、コードを修正するのはかなり簡単です。他のレポートは明らかに理解することが不可能です。あなたが彼らとできることは、それがどの機能であったかを知ることですが、それだけです。
は私が
停止のマクロを使用してインライン化するコンパイラを信頼?必要なデータを取得するだけで、重要な場合は手動で展開します。マイクロベンチマークはマクロの邪魔になりませんか? – bmargulies
@bmarguliesマクロはC++テンプレートをエミュレートします。それはパフォーマンスとは関係ありません。 – user3386109