TGViewer
C++: Хроники Дурки🚑 C++: Хроники Дурки🚑 @cpp_durka · 917 subscribers
Post #7 626
Дисклеймер: я не претендую на невероятною новизну фактов. Я просто показываю всем известные примеры, на которые натыкаюсь раз за разом, раз за разом....

Вот еще один прекрасный пример такой гадости.


#include<iostream>

int main(){
int a, b;
int* p = &a;
int* q = &b + 1;
std::cout << std::hex
<< "p: " << p << "\n"
<< "q: " << q << "\n"
<< std::endl;
}


Мы сделаем указатели на две переменные. Если ставить оптимизацию до O1 включительно (после O2 начинаются вопросы на gcc) то переменные будут объявлены "по порядку", и это будут одинаковые указатели. Просто сравниваем посимвольно.


clang:
Program returned: 0
p: 0x7ffdfaf2696c
q: 0x7ffdfaf2696c

gcc:
Program returned: 0
p: 0x7ffca3076f0c
q: 0x7ffca3076f0c


Внимание, вопрос! Что будет, если мы сравним два одинаковых указателя?


#include<iostream>

int main(){
int a, b;
int* p = &a;
int* q = &b + 1;
std::cout << std::hex
<< "p: " << p << "\n"
<< "q: " << q << "\n"
<< std::endl;
std::cout << (p == q ? "equal" : "not equal")
<< std::endl;
}


И получаем внезапное:


clang:
Program returned: 0
p: 0x7ffd6bd0d16c
q: 0x7ffd6bd0d16c

equal

gcc:
Program returned: 0
p: 0x7ffe3c48696c
q: 0x7ffe3c48696c

not equal


И на самом деле - никаких противоречий со стандартом. Это просто Unspecified (даже не Undefined) Behavior.

Не буду раскрывать всю подноготную, легко этот пример найти где-нибудь на хабре.

Вопрос другой: вот когда на собеседовании в очередной раз задают вопросы типа "разверни список", или "проверь бинарное дерево на наличие циклов".
Вот что будет, если выдать в ответ собеседующему этот пример, и попросить доказать, что сравнение указателей в случае такого дерева/списка будет вообще работать? Без него же такую задачу не решить?

И посмотреть, как хорошо справится с ответом на этот вопрос тот, кто в очередной раз предложит развернуть список.

Хотя, разумеется, можно написать как-то так


int a, b;
auto p = reinterpret_cast<uintptr_t>(&a);
auto q = reinterpret_cast<uintptr_t>(&b + 1);
std::cout << std::hex << p << "\n" //
<< q << "\n" //
<< std::dec << (p == q) << std::endl; //
godbolt.org Compiler Explorer - C++ int main(){ int a, b; int* p = &a; int* q = &b + 1; std::cout << std::hex << "p: " << p << "\n" << "q: " << q << "\n" << std::endl; }
  • ❤ 6
  • 🤯 5
  • 🔥 4
  • 👍 1
More from @cpp_durka
  1. Sep 8, 2026Мошенники заставили пенсионерку из Москвы переписать квартиру на Rust
  2. Aug 31, 2026Всяко разное болезненное есть в С++, из всего болезненного одно из самых болезненных - это…
  3. Aug 24, 2026Если кто не знаком с библиотекой nlohmann/json - она прекрасна. Мои мысли о том, как должн…
  4. Aug 21, 2026#толькосвоимемы Код взят тут. if (dim == 0) idx_dim = i0; else if (dim == 1) idx_dim = i1;…
  5. Aug 17, 2026Ладно, искать баги в компиляторах весело, но недостаточно. Давайте поиграемся в чуть более…
  6. Aug 10, 2026Ладно, разумеется прошлый пост был набросом. Никогда не обновляйте компиляторы без очень с…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →