keresd a hibat - clang++ vs g++

adott az alabbi hibas forras:


#include <math.h>
#include <fstream>
#include <string>

using namespace std;

#define	RES_X	15

inline double
m(double x)
{
	static int	first_run=0;
	float		scale[1];  // igen, ide kell ele egy static

	if (!first_run) {
		first_run=1;
		// hack: ASLR miatt ez egy random helyre mutat
		char	__rand_var;
		srand((unsigned)(long)(&__rand_var));
		for (int i=0; i<1; i++) {
			scale[i]=(rand()%15)*1.0;
		}
	}

	return (sin(x/scale[0]));
}


int
main(int argc, char **argv)
{
	int	x;
	int	y;
	fstream	f;

	f.open("test-m-clang.out", fstream::out);

	for (x=0; x<RES_X; x++) {
		for (y=0; y<RES_X; y++) {
			string	s;
			f << "x: " << x << " = "  << m(x) << std::endl;
		}
	}

	f.close();

	return (0);
}

mely clang++-szal forditva ezt adja eredmenyul:


x: 0 = 0
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 0 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 1 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 2 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 3 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 4 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 5 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 6 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 7 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 8 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 9 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 10 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 11 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 12 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 13 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan
x: 14 = nan

viszont g++-szal fordirva a jo eredemenyt adja:


x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 0 = 0
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 1 = 0.124675
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 2 = 0.247404
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 3 = 0.366273
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 4 = 0.479426
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 5 = 0.585097
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 6 = 0.681639
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 7 = 0.767544
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 8 = 0.841471
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 9 = 0.902268
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 10 = 0.948985
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 11 = 0.980893
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 12 = 0.997495
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 13 = 0.998531
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986
x: 14 = 0.983986

viszont a hiba megtalalasa utan, mind a ketto jo eredmenyt (az eltero eredmenyek a random miatt vannak, a fo "hiba" clang eseteben a nan volt) adott

Hozzászólások

Válasz itt: A first_run static, de a scale nem, ezért az m második meghívásától a scale elemei nem lesznek inicializáltak.

Ugye eltaláltam? :)

ahogy BaT is irta, ez a kod nem inicializalt valtozo hasznalatara epul, ami a c++ szabvany szerint 'undefined behaviour' es egy fordito emiatt *barmit* csinalhat belole. ha erdekel, hogy a gcc altal generalt kod miert 'mukodott', akkor meg kell nezni, hogy az adott gcc verzio milyen asm-et generalt belole, de ennek max elmeleti erdekessege van, szemmel lathatoan az adott clang verzio agresszivabban hasznalta ki a nyelv altal adott lehetosegeket, mint a gcc ;). clang-ben van -fcatch-undefined-behavior amugy, kivancsi vagyok, hogy az megfogna-e ezt futasidoben. ha jobban erdekel az UB, akkor John Regehr irt errol a blogjaban.

Koszi. Igen mar a poszt elott rajottem, hogy ez a hiba, csak erdekessegkent iratam meg, hogy milyen kulonbsegek vannak a ket fordito kozott.
A clang-os kapcsolo viszont haszos, mert errol nem tudtam, azonban nem fogja meg ezt a hibat:


op@opn> make
clang++ -O2 -pipe -pipe -fno-delete-null-pointer-checks -march=core2 -v -I /usr/local/include -O2 -Wall -I . -D__OLIVER_HOST -fcatch-undefined-behavior  -L /usr/local/lib -lglut -lm test.cpp  -o test
FreeBSD clang version 3.1 (branches/release_31 156863) 20120523
Target: x86_64-unknown-freebsd9.0
Thread model: posix
clang++: warning: argument unused during compilation: '-fno-delete-null-pointer-checks'
 "/usr/bin/clang++" -cc1 -triple x86_64-unknown-freebsd9.0 -emit-obj -disable-free -main-file-name test.cpp -mrelocation-model static -mdisable-fp-elim -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu core2 -momit-leaf-frame-pointer -v -resource-dir /usr/bin/../lib/clang/3.1 -D __OLIVER_HOST -I /usr/local/include -I . -fmodule-cache-path /var/tmp/clang-module-cache -O2 -Wall -fdeprecated-macro -fdebug-compilation-dir /home/op/work/devel/bme/grafika-2012_2 -ferror-limit 19 -fmessage-length 116 -fcatch-undefined-behavior -mstackrealign -fgnu-runtime -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-dispatch-method=non-legacy -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/test-ccqBm2.o -x c++ test.cpp
clang -cc1 version 3.1 based upon LLVM 3.1 default target x86_64-unknown-freebsd9.0
ignoring nonexistent directory "/usr/include/c++/4.2/backward/backward"
ignoring nonexistent directory "/usr/bin/../lib/clang/3.1/include"
ignoring duplicate directory "/usr/include/c++/4.2"
ignoring duplicate directory "/usr/include/c++/4.2/backward"
ignoring duplicate directory "/usr/include/c++/4.2/backward"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 .
 /usr/include/c++/4.2
 /usr/include/c++/4.2/backward
 /usr/include/clang/3.1
 /usr/include
End of search list.
 "/usr/bin/ld" --eh-frame-hdr -dynamic-linker /libexec/ld-elf.so.1 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/local/lib -L/usr/lib -lglut -lm /tmp/test-ccqBm2.o -lstdc++ -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o

warning nincs rola - mivel akar a nem inicializalt tombot hasznalni is szoktak - de futasi idoben sincs semmi valtozas
___
info

Legeloszor a asm-et neztem, csak nem ezt a reszet, mivel epp a hetekben indult el egy thread freebsd-current-en, hogy a clang float pointing resze nem megfeleloen mukodik es az iranyba mentem el, de azzal a reszevel nem volt gond, utana atneztem megegyszer a kodot es akkor talaltam meg a valos hibat.

http://lists.freebsd.org/pipermail/freebsd-current/2012-September/03650…
___
info

Többé-kevésbé mindent értek, de ezt nem:

for (int i=0; i<1; i++) {
scale[i]=(rand()%15)*1.0;
}

Ehhez miért is kell ciklus, és miért is tömbváltozó a scale? (Már a deklarációnál se értettem.)

Miért nem úgy csinálod, hogy a futás előtt egyszer kiszámolandó dolgokat egy külön initialize_scale vagy mittomén függvényben a futás előtt egyszer kiszámolod?
Így egyrészt az ilyen bugoktól megóvnád magad, tisztább és világosabb lenne a kód, mert látszana, hogy mi tartozik az inicializációhoz és mi a tényleges számításhoz, ráadásul az m függvényben meg lehetne spórolni az if (!first_run) tesztelést, amit minden híváskor feleslegesen elvégez.