LINUX.ORG.RU

Отключить оптимизации для функции

 ,


1

4

Всем привет, при компиляции с флагом -O0 программа работает идеально, стоит добавить -O1 функция проверки пересечения 2х прямых перестает работать, можно ли отключить оптимизации для этой функции? Код функции:

#define EPS 0.00001f

bool Intersect (glm::vec2 A, glm::vec2 B) {
		glm::vec2 p1 = v1->Pos;
		glm::vec2 p2 = v2->Pos;
		//
		float rTop = (A.y-p1.y)*(p2.x-p1.x)-(A.x-p1.x)*(p2.y-p1.y);
		float sTop = (A.y-p1.y)*(B.x-A.x)-(A.x-p1.x)*(B.y-A.y);
		float rBot = (B.x-A.x)*(p2.y-p1.y)-(B.y-A.y)*(p2.x-p1.x);
		float sBot = (B.x-A.x)*(p2.y-p1.y)-(B.y-A.y)*(p2.x-p1.x);
		//
		if (rBot == 0 || sBot == 0)
			return false;
		//
		float r = rTop/rBot;
		float s = sTop/sBot;

		if (r > EPS && r < 1.0f-EPS && s > EPS && s < 1.0f-EPS)
			return true;

		return false;
	}

есть еще другая функция, через скалярное произведение векторов, но для моей задачи она иногда работает не точно, а эта функция всегда хорошо определяла, есть ли пересечение, или нету.

★★★
Ответ на: комментарий от Int64

и да, расстояние между прямыми — само по себе неточное, и определено с точностью скажем до 1 пикселя(если меньше, то прямые можно считать совпадающими). Т.е. когда ты вычислил наклоны обоих прямых (это довольно точно), ты можешь вычислить и их отношение. Оно и даст расстояние до пересечения(если умножить его на расстояние между прямыми). Это расстояние можно вычислять приближённо, заменив деление разностью. Так ты отсеешь заведомо не пересекающиеся в рассматриваемой области прямые.

На самом деле, это только кажется медленным, но за счёт отсечения большинства вариантов, на практике получается заметно быстрее.

Фактически нас интересуют только те прямые, разность наклонов которых «достаточно большая» по сравнению с самими наклонами. Если разность наклонов (почти) нулевая, то прямые если и пересекаются, то очень далеко. Конкретные числа зависят как от разрешения, так и от размера области.

emulek
()
Ответ на: комментарий от hateyoufeel

Почитай описание вот этого бага, например.

это так важно? Какой-то мутный код проходит, и что? Интересно, а каким местом думал тот, кто ЭТО писал? ЯННП, что там написано, в этом коде.

emulek
()
Ответ на: комментарий от Dendy
#!/bin/sh

uuidgen | sed "y,-,_,;s,.*,#ifndef HEADER_UUID_\0\n#define HEADER_UUID_\0\n\n#endif // #ifndef HEADER_UUID_\0\n,"
Deleted
()
Ответ на: комментарий от Dendy

У header guards нет области применения, в других языках основанных на единицах трансляции уже давно от этого избавились: Java, JavaScript, Python, Objective-C, D, etc.

В других языках этого и не было никогда.

Apple пару лет назад вроде собирались добавить поддержку модулей для C-подобных языков в clang/llvm.

http://llvm.org/devmtg/2012-11/Gregor-Modules.pdf

Но воз и ныне там.

hateyoufeel ★★★★★
()
Ответ на: комментарий от DarkEld3r

Или оно не работает на самом деле?

А... Наконец-то. Последняя версия, правда, 3.4. Ждём релиза.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Компилятор глотает невалидный код и выдает кривой бинарник.

потому что по стандарту есть валидный код, а всё остальное: UB, т.е. поведение не определено. Т.ч. придираешься. Вот если-бы ты мне показал валидный(по стандарту) код, который gcc не по стандарту компиллит — был бы баг.

emulek
()
Ответ на: комментарий от emulek

потому что по стандарту есть валидный код, а всё остальное: UB, т.е. поведение не определено.

Использование необъявленной переменной - это UB? Емулек, ты имбецил.

hateyoufeel ★★★★★
()
Ответ на: комментарий от emulek

http://en.cppreference.com/w/cpp/language/static

Ссылки на стандарт там внизу страницы.

Если разжевать вкратце, баг состоит в том, что, если класс является шаблонным и имеет статические члены, то gcc глотает код, в котором статический член не определён (не путать с объявлением).

~> cat test.cc 
template <typename T>
class C {
    T i;
    static int x;
};
//int C::x = 0;  // <- Без этой строчки компиляция должна фэйлить.
int main() { }
~> g++ test.cc -o test -Wall -pedantic
~>

Емулек, ты идиот.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

А, простите, теперь это линкер перехватывает.

~> cat test.cc                        
#include <iostream>

template <typename T>
class C {
public:
    T i;
    static int x;
};

//int C::x = 0;

int main()
{
    std::cout << C<int>::x << std::endl;
    return 0;
}
~> g++ test.cc -o test -Wall -pedantic
/tmp/ccltZiMe.o: In function `main':
test.cc:(.text+0x6): undefined reference to `C<int>::x'
collect2: error: ld returned 1 exit status

В любом случае, эту ошибку должен отлавливать компилятор, а не линкер.

hateyoufeel ★★★★★
()

float rBot
float sBot

if (rBot == 0 || sBot == 0)

Для таких, как ты, даже специальный варнинг есть: -Wfloat-equal.

Компилятор ему не компилятор... Марш фиксить код! :)

intelfx ★★★★★
()
Ответ на: комментарий от hateyoufeel

The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition.

There shall be exactly one definition of a static data member that is odr-used (3.2) in a program; no diagnostic is required.

Static data members of a class in namespace scope have external linkage

A function template, member function of a class template, or static data member of a class template shall be defined in every translation unit in which it is implicitly instantiated (14.7.1) unless the corresponding specialization is explicitly instantiated (14.7.2) in some translation unit; no diagnostic is required.

A definition for a static data member may be provided in a namespace scope enclosing the definition of the static member’s class template.

A class, a function or member template specialization can be explicitly instantiated from its template. A member function, member class or static data member of a class template can be explicitly instantiated from the member definition associated with its class template.

http://stackoverflow.com/a/7109126

В любом случае, эту ошибку должен отлавливать компилятор, а не линкер.

Как он её будет отлавливать, если он этого делать не должен и не может? Или он не должен уметь g++ -c a1.cc? Это противоречит.

quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Ответ на: комментарий от hired777

да спасибо, давно уже это в гугле нашел ) забыл написать, все работает, сделал через площади треугольников, все равно точку пересечения искать не нужно, оставил этот алгоритм, по вычислениям меньше вроде получается.

Int64 ★★★
() автор топика
Ответ на: комментарий от hateyoufeel

Если разжевать вкратце, баг состоит в том, что, если класс является шаблонным и имеет статические члены, то gcc глотает код, в котором статический член не определён (не путать с объявлением).

Емулек, ты идиот.

я?! Я сказал «шаблонным и имеет статические члены»??

emulek
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.