LINUX.ORG.RU

Сообщения Crocodoom

 

Рекурсивно снесли полтемы по 7.1 (авто)

Проверка списка (list) на изменение, сравнение с другим списком...

Анонимус ругнулся, его сообщение удалили, а вместе с ним и 11 нормальных сообщений.

 

Crocodoom
()

Что делать, если поле класса внутри и снаружи отличается?

Не знаю, что и думать

Есть класс

class evolve                                                                    
{
    public:                                                                     
        float global_time;                                                      
}
Кроме этого есть другие поля и методы, конечно. Однако никакие другие поля не завязаны на global_time, а обращаются к этому полю лишь два метода: конструктор и operator(). Вот, как это происходит:
evolve::evolve(...): ..., global_time(0.0)
{
...
}

void evolve::operator()(float d_time)
{
...
global_time += d_time;
}       

Я создаю экземляр класса (назовём его ev), пытаюсь им пользоваться, но в ev.global_time находится какая-то каша: случайные данные, меняющиеся от запуска к запуску. Но не всё так просто: когда я изнутри класса вывожу для отладки global_time, то там правильное значение!

И это именно то самое поле, а не какая-то локальная переменная или иная путинца в именах, потому что

  • если изнутри класса печатать this->global_time, то точно так же всё ок, значение правильное
  • прошерстил весь проект с помощью grep по слову global_time — ничего лишнего нет.

Была гипотеза, что в каком-то месте в global_time записывается НЁХ, но и она не сработала - потому что в this->global_time лежат правильные данные всё время работы программы, в т.ч. и намного позже инициализации. А ev.global_time во внешнем коде выдаёт фигню сразу же после инициализации ev, и далее.

Все оптимизации отключил, толку 0.

Как такую дичь отлаживать вообще? И почему такое может быть, есть предположения?

 , ,

Crocodoom
()

Конфлит имён с библиотечным кодом

Вот есть строчка

const float gamma = 1.0;

Вылетает ошибка

src/../include/params.hpp:11:13: error: ‘const float gamma’ redeclared as different kind of symbol
 const float gamma = 1.0;
             ^~~~~
In file included from /usr/include/features.h:364:0,
                 from /usr/include/x86_64-linux-gnu/c++/6/bits/os_defines.h:39,
                 from /usr/include/x86_64-linux-gnu/c++/6/bits/c++config.h:507,
                 from /usr/include/c++/6/cstdio:41,
                 from src/four.cpp:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:274:1: note: previous declaration ‘double gamma(double)’
 __MATHCALL (gamma,, (_Mdouble_));
 ^

Что тут можно сделать? Кроме как переименовать свою переменную.

 

Crocodoom
()

Избежать повторения кода с помощью C++11 range-based for

Допустим, есть какие-то единообразные инструкции над несколькими переменными

if(x % 2 == 0) ++x;
if(y % 2 == 0) ++y;
if(z % 2 == 0) ++z;

Как такое делается в современном c++? Я попробовал range-based for, но заработал только вариант с указателями.

for(auto t: {&x, &y, &z})
    if((*t) % 2 == 0) ++(*t);

Reference/dereference тут выглядит явно неуместно. Можно как-то по-другому?

Update

С помощью анонимусов получилось вот такое решение

#include <cstdio>
#include <initializer_list>
#include <functional>

#define rlist(x, ...) (std::initializer_list<std::reference_wrapper<decltype(x)>>({x, __VA_ARGS__}))

int main()
{
    int x = 2, y = 3, z = 4;
    for(auto t : rlist(x, y, z)) if(t % 2 == 0) ++t;
    printf("%d %d %d\n", x, y, z);
    return 0;
}

При использовнии выглядит достаточно прилично (а на макрос можно не смотреть). Требует стандарта C++11. Что с производительностью - пока не знаю.

Update 2

Решение на шаблонах от eao197

#include <iostream>
using namespace std;

template<typename F> void apply_to_all(F &&) {}

template<typename F, typename T, typename... O>
void apply_to_all(F && f, T && x, O && ...other) {
	f(forward<T>(x));
	apply_to_all(forward<F>(f), forward<O>(other)...);
}

int main() {
	int x = 2, y = 3, z = 4, v = 5, w = 6;
        apply_to_all([](int & v) { if(v % 2 == 0) ++v; },
		     x, y, z, v, w);
        apply_to_all([](int v) { cout << v << " "; },
		     x, y, z, v, w);
        cout << endl;
        return 0;
}
На c++14 можно писать auto вместо int в лямбде.

В С++17 за счет if constexpr не нужно будет делать пустую заглушку для прекращения рекурсии вызовов:

template<typename F, typename T, typename... O>
void apply_to_all(F && f, T && x, O && ...other) {
	f(forward<T>(x));
	if constexpr(0 != sizeof...(other))
		apply_to_all(forward<F>(f), forward<O>(other)...);
}

 ,

Crocodoom
()

gcc Ofast: баг или фича?

Столкнулся с тем, что добавление обычного printf меняет результат работы программы.

int3 cell;
for(cell.x = 0; cell.x < cells.x; ++cell.x)
for(cell.y = 0; cell.y < cells.y; ++cell.y)
for(cell.z = 0; cell.z < cells.z; ++cell.z)
{
    int id = cell.x*cells.y*cells.z + cell.y*cells.z + cell.z;
    //printf("%d\n", id);
    float3 moment = moments_ram_raw.get(id);
    ...
}

Эти moment потом записываются в другую область памяти, откуда сохраняются на диск в бинарный формат. Так вот, если раскомментировать printf, то бинарный файл изменится. Выяснилось, что виновик — ключ -Ofast. Замена уровня оптимизации на -O3 решила проблему.

Тем не менее, стоит ли копать дальше, чтобы это зарепортить в багтрекер gcc, или это нормальное поведение для -Ofast?

Версия компилятора gcc version 6.3.0 20170516 (Debian 6.3.0-18)

UPD: Ошибся разделом, перенесите в Development, пожалуйста

Перемещено beastie из desktop

 , , ,

Crocodoom
()

Про плагин vim-xkbswitch на Ubuntu 16.04

Насколько мне известно, этот плагин должен самым удобным для пользователя двух раскладок решением. Однако мне так и не удалось добиться нормальной работы на сабжевой системе (на других не тестировал), в итоге вернулся на keymap (с изменением цвета StatusLine). Здесь я опишу три проблемы, с которыми я столкнулся: одну решил, на вторую забил, а из-за третьей отказался от плагина. Если кто сможет сказать что-то дельное, буду очень признателен! Заодно надеюсь, что впредь эта тема будет помогать и другим вимерам, сейчас в гугле информации практически нет.

  • Существенная задержка переключения языка при выходе в Normal Mode из Insert Mode. Около секунды нет никакой реакции на команды (р,о,л,д и др.) Что помогло: ttimeoutlen=0 Но чем была вызвана проблема, я так и не понял. Скорее всего, баг.
  • При переключении на русский язык загорается третья лампочка индикатора на клавиатуре (Scroll Lock). Счёл это фичей, хотя и довольно странной. Никогда не помню эту лампочку горящей на своём ноутбуке. Решил не трогать, хотя и немного раздражало.
  • Критическая проблема: при двойной смене языка в vim он перестаёт реагировать на команды. Чтобы воспроизвести, нужно
    • Выйти в командный режим с русской раскладке
    • Порадоваться тому, что всё работает
    • Переключить язык на английский. Всё по-прежнему работает
    • Снова переключить на русский. Индикатор Scroll Lock уже не горит, и команд vim не воспринимает
    Этот баг вскрывается не сразу, но обязательно вскрывается, т.к. кроме vim обычно бывает запущено ещё что-то =) И если в другом окне был другой язык, то при возврате в vim всё накрывается медным тазом.

 ,

Crocodoom
()

RSS подписка на новые темы