Простая и интересная задачка по C++

Всем привет, я сам ещё новичок в C++(< 2 лет изучаю), но уже что-то понимаю и решил сделать задачу на основы языка для совсем зелёных, для решения из C++ вам нужно будет знать функции, cout и указатели.


Итак, задача:

Дан следующий код: http://pastebin.com/5ehUmhZB


Результат его выполнения:

Hello, World
secret function 42

Вопросы:

1 Почему выводится secret function 42, если вызывается только printHelloWorld(); 

2 Откуда взялось число 42?


Подсказки:

1 Не потому что 42 - это ответ на «главный вопрос Жизни, Вселенной и Всего Остального»

2 На других архитектурах и компиляторах результат может быть другим, я компилил в linux gcc 5.4.0 x64


P.S. Если не верите, можете убедиться сами https://www.tutorialspoint.com/viewproject.php?URL=compile_cpp_online.php&PID=0Bw_CjBb95KQMTW9WaTliUXRqc1U

Лига программистов C/C++

62 поста4.8K подписчиков

Добавить пост

Правила сообщества

Соблюдайте правила Pikabu:

https://pikabu.ru/html.php?id=wtf


Помимо этого ЗАПРЕЩЕНО:

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

Автор поста оценил этот комментарий

Я не говорил что это не возможно. Только вот поробуй добавь туда еще какую-нибудь платформу, давай возьмем арм даже с тем же линуксом на борту так ли все легко и гладко будет?

Когда одной из задач является переносимость - это сделать гораздо проще, но как практика показала писать переносимый код та еще проблема и она посерьезнее, чем твои выкрутасы с UB.

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

Причем тут Qt? В том то и дело что не компилится, а как только ты его все таки собираешь вылазит огромное количество багов, даже при просто переходе от x86 на x86_64. Не говоря уже о других ОС и архитектурах. Да хрен с ним, даже просто другим компилятором собрать проблема и баги даже там лезут!

раскрыть ветку (1)
Автор поста оценил этот комментарий
Вот например большой проект на Qt https://github.com/goldendict/goldendict (не мой, если что) и он прекрасно компилится под разные платформы.
показать ответы
Автор поста оценил этот комментарий
Я конечно понимаю, что буду выглядеть как школьник, который на уроке математики спрашивает, а как это применить в реальной жизни, но все же спрошу. А накой ля так извиваться? Да и не надо это новичкам, каковым я себя считаю. Для нас лучше пока использовать shared_ptr, auto, и что-то попроще, а не извиваться с памятью и стеком.
раскрыть ветку (1)
Автор поста оценил этот комментарий
Вы правы на счёт того, что использовать такое в рабочем коде не стоит, и надо было об этом написать в посте. А пример просто для демонстрации того, что такое возможно. Единственное логичное применение подобных извращений - написание вредоносных программ или взлом, раньше часто взламывали программы, подавая на вход больше символов чем нужно, допустим если массив размещён на стеке и выход за границы не контролируется, то можно таким же образом записать нужный код и программа либо упадёт либо сделает не то, что нужно было.

А на счёт shared_ptr, его тоже нужно понимать и везде пихать его не стоит, в некоторых случаях нужен unique_ptr или weak_ptr.

показать ответы
Автор поста оценил этот комментарий

что ты завелся то? как девочка ей-богу. не ныл бы, а мотал на ус пока советы бесплатные дают.

раскрыть ветку (1)
Автор поста оценил этот комментарий

Офигенный совет, "пиши переносимый код", это как сказать "пиши читаемый код", "пиши полезные программы" и т.д. Во первых, это не везде нужно, некоторые программы пишутся, допустим под мобилку и портироваться на ПК не будут и наоборот, а во вторых, мне твои "советы" не нужны.

показать ответы
1
Автор поста оценил этот комментарий

Такого количества говнокода я в одном месте 100 лет не видел! = )

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

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

Вы не поняли, #include <iostream> включает ВЕСЬ iostream. using std::cout лишь добавляет ::cout как синоним ::std::cout в список существующих классов, не более (или, наоборот, при поиске ::cout так же ищет ::std::cout). То есть разницу можно заметить, если вы делаете using namespace %NAMESPACE% для ста пространств имён и двухсот подключаемых заголовочников. В обратном случае, вы замедляете разбор файла разбором дополнительных строк.


Ну и используйте uintptr_t для хранения указателей. Для чего он ещё нужен-то?

раскрыть ветку (1)
Автор поста оценил этот комментарий

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

показать ответы
Автор поста оценил этот комментарий

Я - нет. using std::cout; - да. Борланд слишком стар для этого дерьма.

раскрыть ветку (1)
Автор поста оценил этот комментарий

А, ну тогда юзайте using namespace std; 

5
Автор поста оценил этот комментарий

Нет. "Подключается мусор" директивой include, using лишь определяет используемые пространства имён. Теоретически, замедление в ноль целых хрен тысячных будет, но по факту единственная причина указывать поклассовое using - борьба с пересечением имён. До тех пор, пока вы не делаете платформозависимые  реализации каких-либо действий, и не конфигурируете их с помощью манипуляции пространствами имён, делать этого не стоит.

раскрыть ветку (1)
Автор поста оценил этот комментарий

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

показать ответы
2
Автор поста оценил этот комментарий

Компилиться должно, но вот работать правильно - не факт.

раскрыть ветку (1)
Автор поста оценил этот комментарий

Те, кто минусуют, считают иначе?

показать ответы
12
Автор поста оценил этот комментарий

За такие манипуляции со стеком - расстрел через повешение без права досрочного освобождения.

раскрыть ветку (1)
2
Автор поста оценил этот комментарий

Я ж не говорю, что это хороший стиль программирования)

Автор поста оценил этот комментарий

Пробовал откомпилить на DevCpp и Borland C++, не получилось :(

Поэтому, почему 42, так и не понял.

Ну а с секретной функцией вроде ясно (теоретически)

раскрыть ветку (1)
2
Автор поста оценил этот комментарий

Компилиться должно, но вот работать правильно - не факт.

показать ответы
Автор поста оценил этот комментарий

я конечно совсем ноль в программировании, но разве нельзя было использовать строку "using namespace std" вместо

using std::cout;

using std::cin;

using std::endl;

раскрыть ветку (1)
Автор поста оценил этот комментарий

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

показать ответы
8
Автор поста оценил этот комментарий

long *ptr = (long *)&ptr + 3;

*ptr = (long)&func1;

В стеке есть адрес возврата из printHelloWorld, вместо него вставлен адрес func1.

*((int *)ptr - 1) = 052;

"var", который в другой функции, тоже находится в стеке и здесь мы его фиксим на значение 42.


Короче, такой фигнёй лучше на ассемблере заниматься -- понятнее и портабельнее будет.

раскрыть ветку (1)
3
Автор поста оценил этот комментарий

Правильно, держи печеньку

Иллюстрация к комментарию