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

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

Суть, разумеется, не в этом.

Посмотрите на строку №52. Там просто печатается буква F. Она то каким боком к тому нулю?

Или, например, в самый конец функции setup добавьте:

Serial.println(11);
Serial.println(33);

Убедитесь, что тоже строка не переводится и попробуйте объяснить, эти-то строки каким боком к тому нулю?

Уж полночь близится, а Петрович все никак не колется )))

2 лайка

неделю мучений просто так сдать? надо продлить интригу

1 лайк

Я ничего специально не гуглил (да и понятия не имею - что именно тут гуглить нужно), но есть такое предположение (хоть и много сегодня говорилось о строковых константах (или как там их правильно), но всё же «дьявол кроется в мелочах»).

Есть что-то в функции Serial.print/Serial.println такое интересное, может быть даже «глобальное», что заставляет println опускать «перевод каретки» и досрочно завершать работу. К сожалению, я не могу так глубоко копать как многие из постоянных участников данного форума, поэтому только «намеки» и «предположения»…

1 лайк

Прямого воздействия на инстанс Stream-а не наблюдается.

1 лайк

Не знаю по какой причине Евгений Петрович отметил мой предыдущий пост «лайком», возможно хочет ввести в заблуждение.

Но есть же умные люди среди нас, @MMM посмотри от какого родителя идет Serial.print , возможно в этом кроется всё?

Я еще могу припомнить @sadman41 (но что-то не хочет), @xDriver, @andriano (но тот скорее всего уже знает и просто даёт фору Петровичу), @andycat вообще молчит, @Kakmyc вроде бы высказывался (но смотрел ли полиморфизм (если не ошибаюсь)?). Простите если еще кого забыл, можно отметиться ответом )

@ЕвгенийП - официально хочу сказать, если это и не самый «запутанный вопрос», то самый интересный!!! :slight_smile:

Прямая подсказка есть в этой теме. Я её случайно выболтал, но убирать уже не стал :slight_smile:

Работы много, забегу, почитаю, понял что нифига не понял, ушёл :slight_smile:

Так то, работая с char строками, правду можно понять только получив строку в hex, подозреваю что монитор порта определённые последовательности байт воспринимает не так, как хотелось бы программисту.

Я всё в коде искал ошибку, но получается она в компиляторе?

А это частично мою версию подтверждает

Остается в памяти огрызок
\n
с нуль терминатором, только что это меняет?

Да, нет, конечно же, в коде.

я тока одно нехорошее слово знаю, на “F” )))

А можно уточняющий вопрос?
В коде представленном Вами или же в «дебрях» используемых функций?


char * Message = "\r\n";

void setup (void) {

  Serial.begin(9600);

  Serial.println(0);

  *(Message) = 0;
  Serial.println("1");
  Serial.println("2");
  Serial.println("3");

  *(Message) = '\r';
  Serial.println(" ");
  Serial.println("1");
  Serial.println("2");
  Serial.println("3");
}

void loop(void) {}

А потом закоменте 7 строку)))

Да он ждёт, когда вы догадаетесь…
А по факту: литералы и спецсимволы(\l,\r,\n в их числе), “константами” хранятся в памяти в одном экземпляре а вызываются через указатель по адресу.
Он тупо засирает своим “говнокодом” адрес где лежит спецсимвол переноса строки значением 0.
А так как засрал однажды, работает это уже всегда, ну или можно обратно “перезасрать” :slight_smile:

2 лайка

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

А это уже описывалось в предыдущих выпусках говнокода.
Проверить можно тупо создав несколько разных строк с одинаковым содержимым и сравнив размер памяти.
В этом случае размер памяти не будет изменяться на размер строки, а только на размер указателя. Ну и соответственно говнокодом испоганив одну из строк (которая константная) испоганятся все разом, так как по факту эта одна и та же строка.

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

Скажем так, при вызове метода Serial.println() вызывается строка “\r\n”, которая уже прописана в памяти как строка из литералов и имеет свой адрес.
При каждом новом появлении такой же строки в коде компилятор тупо линкует ссылку на этот адрес…

2 лайка

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