Говнокод по пятницам. Эпизод 3. «Serial.println vs. Imperial Starfleet»

Если бы вы/ты с присущим занудством, еще обьяснили ПОЧЕМУ, я лично бы, стал оценивать вас с другово ракурса))

Чет наш всезнайка молчит🤔

1 лайк

Так, я спать, голова уже распухла, ночной колпак боюсь не натяну.

Я понимаю что от таких задач голова у всех пухнет, нет - раньше чем ты.

Вы хотите, чтобы я пересказал то, что уже написано в этой теме?
Этот эффект называется порчей константы.
Имеет самые разные проявления.
Вспомнился классический пример на Фортране:

  SUBROUTINE SUB(N)
  IMPLICIT NONE
  INTEGER N
  IF(N .GT. 0) N = 0
...
  END

  ...
  CALL SUB(1)
*  далее везде, где будет встречаться единица, вместо нее будет подставлен 0

Как Вы думаете, я в этом сильно нуждаюсь?

1 лайк

Я тебя умоляю, переадресуй это все нашему герою @ua6em -у, он найдет что тебе сказать.

Что-то подзаглохло. Ждем-с.

Больше всего меня удивляет то, что это уже было проделано, причем почти все присутствующие здесь, присутствовали и там, но никто про это не вспомнил! Так быстро забылось?

Т.е. ларчик открывается просто. Компилятор помечает все литералы таковыми, но не размещает их в памяти, оставляя это компоновщику (т.е. оставляя на момент, когда все файлы уже откомпилированы). Тот начинает размещать выбрасывая одинаковые и склеивая те, которые можно склеить в один без ущерба функциональности. Ну, а что Вы ему их плодить предлагаете? Таким образом, если где-то (в любом файле) был литерал “12345”, а где-то был “45”, он оставит только первый, в второму даст “адрес первого + 3”.

Поэтому после моего сообщения #12, я подумал, что интрига умерла, т.к. если сопоставить его с примером по ссылке выше, всё становится предельно понятным. println использует литерал "\r\n", компоновщик совместил его с наши литералом, который оканчивается так же, а мы его загадили :frowning:

Золотые слова. Согласен абсолютно. То, что Вы видите здесь – каприз художника, просто я так развлекаюсь.

На последок, примерчик “полезного” использования этого говнокода (реально “полезного”, но Боже меня упаси его кому-то советовать. Говнокод – он и есть говнокод. Так что, снова каприз художника).

Итак, создаём структуру, которая умеет печататься в поток (леденящую кровь историю про Имперский флот и звонок Дарта Вейдера сами допишите) и пишем

проверочный код
struct SomeStruct : public Printable  {
	int a, b, c, d, e, f, g, h;

	SomeStruct(const int _a, const int _b, const int _c, const int _d) : a(_a), b(_b), c(_c), d(_d) {
		e = a + b;
		f = c + d;
		g = e + f;
		h = g - f;
	}

	size_t printTo(Print& p) const { 
		size_t res = p.print('{');
		res += p.print(a);
		res += p.print("; ");
		res += p.print(b);
		res += p.print("; ");
		res += p.print(c);
		res += p.print("; ");
		res += p.print(d);
		res += p.print("; ");
		res += p.print(e);
		res += p.print("; ");
		res += p.print(f);
		res += p.print("; ");
		res += p.print(g);
		res += p.print("; ");
		res += p.print(h);
		res += p.print('}');
		return res;
	}
};

void setup(void) {
	Serial.begin(9600);
	SomeStruct ss(1,2,3,4);
	Serial.println(ss);
}

void loop(void) {}

Запускаем и получаем ожидаемый результат.

{1; 2; 3; 4; 3; 7; 10; 3}

А теперь заменим функцию печати на

вот такую (с нашим говнокодом)
	size_t printTo(Print& p) const { 
		constexpr static char * const brbn = (char *) "\r\n";
		size_t res = p.print('{');
		* brbn = ';';
		* (brbn+1) = ' '; 
		res += p.println(a);
		res += p.println(b);
		res += p.println(c);
		res += p.println(d);
		res += p.println(e);
		res += p.println(f);
		res += p.println(g);
		* brbn = '\r';
		* (brbn+1) = '\n'; 
		res += p.print(h);
		res += p.print('}');
		return res;
	}

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

2 лайка

Не понял в чем прикол юзать этот “ln”, когда можно прямо писать "\r\n " в любом месте мессага. И в начале, и в конце и в середине.
А “\r” удобно юзать для вывода, скажем, секунд в том же месте. Просто после них добавим еще вывод пробелов, чтобы они стирали предыдущее.
Сорри если я не вник в контекст данной проблемы println(); ахаха.

Бывает.

Первый точный ответ, не намек, дал Кактус в 75 сообщении.
Я не автор и с ним не общаюсь ;), но публичный совет даю - как-то поощрить стоит человека, нет?

И в догонку - оптимизацию размещения литералов естественно можно отключить.

1 лайк

Я лично только “за”. Но как?

Сайт безмонетный.
Фонд с выделением премий? Кто распоряжаться, распределять, критерии полезности. Добровольно? Куда?

Отметить #75 пост как «Вопрос решен»?

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

Наши сотрудницы, например, вернувшись из увлекательного отпуска, постоянно задают вопросы по АРМу, в котором работают годами.

А что, других поощрений кроме материальных в природе не существует?
Вот, например, в качестве наводки:

( Указ Президента РФ от 10.11.2007 N 1495)

1 лайк

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

Можно разрешить ему неделю матерится на форуме, не боясь бана.

2 лайка

Фото на фоне знамени - это временная замена логотипа форума на аватар кактуса?

2 лайка

“Экий ты меркантильный, Маргадон …”

И за буйки заплывать, а, главное, расконстанчивать литералы!

А можно меня просто в закрытые темы пустить ?

Без вот этих вот ваших угарных стебов

2 лайка