LINUX.ORG.RU

Будь проклят тот день #3 [С++ template hell]

 ,


0

2

Снова MSVC против g++ :

template <typename TIndex>
struct CVertexManagerFixed
{
    template <typename TPathBuilder, typename TCompoundVertex>
    class CDataStorage : public TPathBuilder::template CDataStorage<TCompoundVertex>
    {
    public:
        using CDataStorageBase = typename TPathBuilder::template CDataStorage<TCompoundVertex>;
        using Vertex = TCompoundVertex;
        using Index = TIndex;

    public:
        inline CDataStorage(const u32 vertex_count);
        inline virtual ~CDataStorage();
        inline Vertex& get_node(const Index& vertex_id) const;
    };
};


#define TEMPLATE_SPECIALIZATION                           \
    template <typename TIndex> \
    template <typename TPathBuilder, typename TCompoundVertex>

#define CFixedVertexManager \
    CVertexManagerFixed<TIndex>::CDataStorage<TPathBuilder, TCompoundVertex>

TEMPLATE_SPECIALIZATION
inline CFixedVertexManager::CDataStorage(const u32 vertex_count)
    : CDataStorageBase(vertex_count)
{
}

TEMPLATE_SPECIALIZATION
inline typename CFixedVertexManager::Vertex& CFixedVertexManager::get_node(const Index& vertex_id) const
{
    VERIFY(vertex_id < m_max_node_count);
    VERIFY(is_visited(vertex_id));
    return *m_indexes[vertex_id].m_vertex;
}

Лог ошибок:

../src/test_cpp.cpp:54:34: error: non-template ‘CDataStorage’ used as template
     CVertexManagerFixed<TIndex>::CDataStorage<TPathBuilder, TCompoundVertex>
                                  ^
../src/test_cpp.cpp:63:17: note: in expansion of macro ‘CFixedVertexManager’
 inline typename CFixedVertexManager::Vertex& CFixedVertexManager::get_node(const Index& vertex_id) const
                 ^
../src/test_cpp.cpp:54:34: note: use ‘CVertexManagerFixed<TIndex>::template CDataStorage’ to indicate that it is a template
     CVertexManagerFixed<TIndex>::CDataStorage<TPathBuilder, TCompoundVertex>
                                  ^
../src/test_cpp.cpp:63:17: note: in expansion of macro ‘CFixedVertexManager’
 inline typename CFixedVertexManager::Vertex& CFixedVertexManager::get_node(const Index& vertex_id) const
                 ^
../src/test_cpp.cpp:54:59: error: expected unqualified-id before ‘,’ token
     CVertexManagerFixed<TIndex>::CDataStorage<TPathBuilder, TCompoundVertex>
                                                           ^
../src/test_cpp.cpp:63:46: note: in expansion of macro ‘CFixedVertexManager’
 inline typename CFixedVertexManager::Vertex& CFixedVertexManager::get_node(const Index& vertex_id) const
Я не понимаю, почему объявление возвращаемого типа метода get_node дает такую ошибку. Ведь CDataStorage - это только шаблон, нигде как класс он не объявлен?

★★★★★

g++ же всё сказал:

note: use ‘CVertexManagerFixed<TIndex>::template CDataStorage’ to indicate that it is a template

Я не понимаю, почему объявление возвращаемого типа метода get_node дает такую ошибку. Ведь CDataStorage - это только шаблон, нигде как класс он не объявлен?

Потому что он его и за тип не считает, по умолчанию зависимые члены же вроде как методы/поля проходят и надо явно указывать typename или template.

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

Студия ещё и не такое жуёт. Смотря какая, правда. Последние версии стали более уважительны к стандарту.

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

Эта как раз последняя. Насчет уважения к стандарту - тут остается только заплакать, смотри первую тему с таким названием.

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

Дак вроде вот же? Последние строки:
inline typename CFixedVertexManager::Vertex& CFixedVertexManager::get_node(const Index& vertex_id) const

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

Так а макрос?

-#define CFixedVertexManager \
-    CVertexManagerFixed<TIndex>::CDataStorage<TPathBuilder, TCompoundVertex>
+#define CFixedVertexManager \
+    CVertexManagerFixed<TIndex>::template CDataStorage<TPathBuilder, TCompoundVertex>

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

Там вроде можно выбрать стандарт где-то. И уже давно видел галку «не использовать расширения MS». Но не знаю, всё оно ловит или как.

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

Пропустил, что оно в двух разных контекстах используется. template надо только для возвращаемого типа, в объявлении метода компилятор понимает, что там не переменная. В общем одним макросом не обойтись.

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

Насчет уважения к стандарту - тут остается только заплакать

это ты еще clang не видел...там такой ад (свой собственный стандарт С++, может даже больше)

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

Сейчас студии надо выставлять Conformance mode. Но пока все равно есть расхождения со стандартом при разрешении имен.

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

Смотря что считать студй. Под маки однозначно ксамарин - сами MS не осилили, пришлось купить. Тот же monodevelop, которому сто лет и который работает!

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

Толсто.

Помогите разобраться, это баг LLVM или нет

в последнем проекте ( https://github.com/danilw/Castle-game/blob/master/agame3k.cpp смотри комменты по ходу) проблема по ссылке разрослась до того что теряются static const

чем больше кода-тем clang-у становиться хуже

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

в последнем проекте ( https://github.com/danilw/Castle-game/blob/master/agame3k.cpp смотри комменты по ходу) проблема по ссылке разрослась до того что теряются static const

Да уж, лютый говнокод. Вы бы это, сперва C++ в минимальной степени освоили бы, потом бы уже претензии clang-у предъявляли.

Например, в addstring память выделяется через new, а чистить ее кто будет, Пушкин?

Подозреваю, что в вашем коде полно UB и clang их очень жестко оптимизирует. Настолько, что ваша говнолапша просто перестает работать.

Попробуйте прогнать свой код через какой-нибудь более-менее вменяемый статический анализатор или запустить со включенными санитайзерами. Не удивлюсь, если вы обнаружите много интересного для себя.

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

Через /permissive-, это раз. Два: это не особо включает уважение к стандарту, а только отключает пару расширений студии.

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

Детали в студию(не в эту)! -std=c++xx -pedantic-errors не забудь

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

Да уж, лютый говнокод. Вы бы это, сперва C++ в минимальной степени освоили бы, потом бы уже претензии clang-у предъявляли.

прочиталбы ты для начала что такое WASM и без Си вставок он банально не работает

Например, в addstring память выделяется через new, а чистить ее кто будет, Пушкин?

эти данные передаются в джаваскрипт в функции postit, джаваскрипт их принимает и они «уходят»(не копируются) на сторону джаваскрипта, и из джаваскрипта мне нужно вызывать уже -_free после использования(этого я конечноже не делаю, ибо и так работает)

Подозреваю, что в вашем коде полно UB и clang их очень жестко оптимизирует. Настолько, что ваша говнолапша просто перестает работать.

сделаю бинарный билд на днях, тогда посмотрим

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

и без Си вставок он банально не работает

Да похрен на C-шный код, у вас C++ный код фееричен. Одна вышеупомянутая addstring чего стоит. Наглядное подтверждение тезиса о том, что программу на Фортране можно написать на любом языке.

из джаваскрипта мне нужно вызывать уже -_free после использования(этого я конечноже не делаю, ибо и так работает)

Прекрасно.

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

у вас C++ный код фееричен. Одна вышеупомянутая addstring чего стоит.

addstring это Си код, вне extern C, ибо внутри он не работает(с малоками, они чистятся до того как джаваскрипт чтото успеет принять)

вот какбы ты сделла, тебе нельзя использовать std::string (c_str надо копировать в любом случае), нельзя малоки, нельзя делите(ибо оно на стороне джаваскрипта)

какбы ты отправил данные функцией emscripten_run_script(*char) для которых надо выделить память

забыл сказать strcat тоже не копирует память

добро пожаловать в clang

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

И причём здесь clang? У тебя просто сложный контекст, который ты разрулил костылями и где-то допустил UB

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

И причём здесь clang?

тоесть то что strcat не копирует память это норма?
окей понял принял

все пляски в коде особенно максимально бредовые, сделаны чтоб «оно работало» ибо без них оно не работает
вот такой классный метод разработки, пишу код он либо работает либо нет,если нет и оказывается что все стандартные функции Си и С++ работают совсем не так как они должны(ведь нигде не сказано что strcat должен копировать память ага)

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

addstring это Си код

Как все запущено. Сколько вам лет? Как давно взялись код писать?

Теперь по сути.

Вы в addstring используете глобальные переменные, хотя это вообще не нужно.

Вот это вот что за феерия:

    for (int i = 0; i < c_map.length(); i++) {
        int randomNum = uni(rng);
        ts += c_map.substr(randomNum, 1);
    }
Это вам нужно строку из случайных цифр сделать? Почему бы сразу случайные цифры не генерировать, без c_map и модификации c_map.

забыл сказать strcat тоже не копирует память

Возможно, у вас в наличии есть strdup. Если нет, то его легко сделать самому, чтобы new+strcpy не копипастить.

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

Ты сам здесь пишешь:

вне структуры того проекта этот баг не работает

Значит, в остальных случаях strcat таки копирует. Соответственно, баг в твоём коде, хотя вероятность ошибки в компиляторе/кодогенераторе тоже имеется

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

strcat

Да тут клондайк просто:

The behavior is undefined if the destination array is not large enough for the contents of both src and dest and the terminating null character. The behavior is undefined if the strings overlap. The behavior is undefined if either dest or src is not a pointer to a null-terminated byte string

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

тоесть то что strcat не копирует память это норма?

Это в каком таком сценарии strcat «не копирует память»? Покажите пример.

вот такой классный метод разработки, пишу код он либо работает либо нет,если нет и оказывается что все стандартные функции Си и С++ работают совсем не так как они должны(ведь нигде не сказано что strcat должен копировать память ага)

Ну т.е. «ни x*я не знаю, ни х*я не умею, ни х*я не хочу учится», а виноват при этом clang?

Прекрасно, просто прекрасно.

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

Вот это вот что за феерия:

в игре есть Leaderboard и данные на сервер шифруются в си коде(банально) чтоб избежать читеров и спама, исходники генерации ключей я не добавлял(вырезал) оставив лишь это, это пустой код по сути

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

Значит, в остальных случаях strcat таки копирует.

да если «результирующас строка» не вступает в отношения скалбеками и отправкой в джаваскрипт(тоесть делается вид что копируется)

или в другой версии clang тоже возможно

в прошлой версии(пару месяцев назад обновили) clang компилятора(с их сайта версьию непомню точно) не работало например int aa[100]={0}; сейчас это работает но много чего еще\уже нет

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

Ну т.е. «ни x*я не знаю, ни х*я не умею, ни х*я не хочу учится», а виноват при этом clang?

не брат, ты просто не компируешь clang-ом поэтму не в курсе что стандарт Си определяет компилятор

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

Это в каком таком сценарии strcat «не копирует память»? Покажите пример.

вот в этом коде https://github.com/danilw/WebServer/blob/master/source/main.c (он собирается портом GCC под целевую платформу)

все методы из #define k_mem не работают, а там по сути только копирование памяти
там тоже «такой стандарт Си» в котором чтото работает не так как ожидается

аналогично с версией clang

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

да если «результирующас строка» не вступает в отношения скалбеками и отправкой в джаваскрипт

С -O0 ситуация повторяется?

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

все оптимизации -О0 -О3 включительно выключены по дефолту(по какойто причине(возможно из за этих атак на процессор Спектр или как там)) в компиляторе под wasm последнем(в предыдущей версии работает) код генерируется идентичный с люыми опциями(все работает одинаково)

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

Вы конкретный пример того, как strcat не работает привести можете? Или будете ссылаться на какие-то простыни кода, которые вы толком скопипастить не можете?

PS. clang-ом пользуюсь давно, ни с C++11, ни с C++14, ни теперь с C++17 проблем никаких не имею.

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

Кстати, из той же твоей темы:

если:
1. переместить(копипастить) весь метод init в main (в функцию из которой вызывать каллбек) то проблема исчезнет(все калбеки работают)
2. сделать local_foo1 local_foo2 глобальныи - тоже все калбеки заработают

Намекает на обращение к неинициализированному объекту

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

все оптимизации -О0 -О3 включительно выключены по дефолту(по какойто причине(возможно из за этих атак на процессор Спектр или как там))

Лолшто ?-) Я говорил о том, проявляется ли баг с _отключенной_ опимизацией

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

Вы конкретный пример того, как strcat не работает привести можете?

1. качаешь emscripten последней версии, идешь сюда https://github.com/kripken/emscripten/tree/incoming/tests

начинаешь собирать, и у тебя половина тестов провалена

2. качаешь предыдущую версию emscripten идешь тудаже, и кайфуешь у тебя другая половина тестов провалена

ну или сам пишешь чтото сложнее хеловорда

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

Так вы чем недовольны: clang-ом или emscripten-ом?

Если у вас проблемы с clang-ом, то покажите пример.

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

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

657 int getlgth() {

loruser: error: no 'static const int' in this line :)

Anyway, у тебя там дофига кода, возможностей пропустить UB ещё больше. И для того, чтобы доказать баг в компиляторе, тебе всё равно нужно сделать минимальный пример. Вот уже с ним можно будет работать, а не тыкать пальцем в небо. Пока нет примера не более пары десятков строк - разумно считать что бага у тебя(это c++ детка, ага:). А пока только рыскать по коду с отладчиком наперевес

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

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

все врено брат, рот твой ебал по этомуже поводу даун

ничего личного (сдохни)

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

тебе всё равно нужно сделать минимальный пример

офф тестовемскриптена не хватает да?

я даже второй пример с ГЦЦ привел выше

покимпилируйте чтото не на x86/64 платформу, мой опыт не уникальный, все с этим сталкиваются

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

офф тестовемскриптена не хватает да?

Не до конца распарсил, но видимо ты имеешь ввиду что без emscripten пример не сделать. Ну да, возможно бага в нём. Попробуй всё таки собрать свой код без оптимизации(-O0, никаких -O2/-Os/-O3/-Ofast)

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

ты просто не компируешь clang-ом

У меня С++ проект собирается на clang gcc msvc, в том числе на mingw, и 64, и 32 бит. При этом там тонна генеренного кода, никакого GUI.

Не вижу причин, кроме нубства, почему Си и Си++ коду не работать как должно.

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

Не вижу причин, кроме нубства, почему Си и Си++ коду не работать как должно.

тоесть ты щас разрабов llvm из гугла/апла нубами назвал? окей понял принял

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

по секрету скажу, если собрать Box2d clang-ом, будет утечка памяти при удалении объектов (функцией box2d)

это спустя 20+ лет раработки разработчики Bpx2d нубы? или разработчики clang? помогите разобраться непойму

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