Понятно, что компиляция файлов проходит без ошибок
Но почему все собирается без ошибок?
У лямбд внутреннее связывание, как у констант ?
Или это связано с выводом типов и у них таки разный тип получается ?
Где про это прочитать ?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Вопрос про лямбды - нашел ответ на StackOverflow на русском
Тип объекта замыкания (closure object), порождаемого лямбда-выражением, никак не зависит от параметров лямбды и не определяется ими.
Наличие или отсутствие аргументов по умолчанию здесь никакой роли не играет.
Каждое лямбда-выражение порождает новый уникальный тип — это все, что вам нужно знать о типе объекта замыкания.
Даже если два лямбда-выражения полностью идентичны, они все равно получат никак не связанные друг с другом уникальные типы.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
LVV>Понятно, что компиляция файлов проходит без ошибок
LVV>Но почему все собирается без ошибок? LVV>У лямбд внутреннее связывание, как у констант ? LVV>Или это связано с выводом типов и у них таки разный тип получается ? LVV>Где про это прочитать ?
The lambda expression is a prvalue expression of unique unnamed non-union non-aggregate class type...
То есть, каждая лямбда по определнию уникальна, и уже на этом основании не составит коллизии ни с какой другой лямбдой, даже если они рядышком и полностью одинаковые будут. Ну и в нагрузку, она еще и безымянна, то есть, на уровень линковки вообще не выходит, следовательно, никаких конфликтов там быть не может из за "одинаковых лямбд".
Здравствуйте, vopl, Вы писали:
V>То есть, каждая лямбда по определнию уникальна, и уже на этом основании не составит коллизии ни с какой другой лямбдой, даже если они рядышком и полностью одинаковые будут. Ну и в нагрузку, она еще и безымянна, то есть, на уровень линковки вообще не выходит, следовательно, никаких конфликтов там быть не может из за "одинаковых лямбд".
Здесь дело не в лямбдах, а в глобальных переменных next_operands. За счет разных типов коллизии нет.
Здравствуйте, andrey.desman, Вы писали:
AD>Здравствуйте, vopl, Вы писали:
V>>То есть, каждая лямбда по определнию уникальна, и уже на этом основании не составит коллизии ни с какой другой лямбдой, даже если они рядышком и полностью одинаковые будут. Ну и в нагрузку, она еще и безымянна, то есть, на уровень линковки вообще не выходит, следовательно, никаких конфликтов там быть не может из за "одинаковых лямбд".
AD>Здесь дело не в лямбдах, а в глобальных переменных next_operands. За счет разных типов коллизии нет.
Ну, давай попробуем эту мысль подумать. Если в приведенном ТС куске кода next_operands это глобальная переменная, объявляемая в двух единицах трансляции — то линкер безусловно будет ругаться на нее. То есть, это не ситуация ТС... Или это именно та ситуация? Тогда ТС что то упустил, так как в этом случае ошибка линкера таки будет иметь место.
Я так понял, что у него next_operands не является глобальной переменной. ТС вообще говорит о лямбде а не о next_operands.
LVV>Есть два исходных файла 1.срр и 2.срр LVV>В обоих определена одна и та же лямбда на глобальном уровне
LVV>все собирается без ошибок
/usr/bin/ld: /tmp/cc5qfXUR.o:(.bss+0x0): multiple definition of `next_operands'; /tmp/ccAK4JPQ.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
Здравствуйте, vopl, Вы писали:
AD>>Здесь дело не в лямбдах, а в глобальных переменных next_operands. За счет разных типов коллизии нет. V>Ну, давай попробуем эту мысль подумать. Если в приведенном ТС куске кода next_operands это глобальная переменная, объявляемая в двух единицах трансляции — то линкер безусловно будет ругаться на нее. То есть, это не ситуация ТС... Или это именно та ситуация? Тогда ТС что то упустил, так как в этом случае ошибка линкера таки будет иметь место.
А, ну да, глобалы не манглятся... Судя по всему, у него какой-то странный компилятор или код не весь.
V>Я так понял, что у него next_operands не является глобальной переменной. ТС вообще говорит о лямбде а не о next_operands.
Так о самой лямбде смысла нет говорить, с ней и так все понятно.
LVV>>Есть два исходных файла 1.срр и 2.срр LVV>>В обоих определена одна и та же лямбда на глобальном уровне
LVV>>все собирается без ошибок σ>
/usr/bin/ld: /tmp/cc5qfXUR.o:(.bss+0x0): multiple definition of `next_operands'; /tmp/ccAK4JPQ.o:(.bss+0x0): first defined here
σ>collect2: error: ld returned 1 exit status
Один и тот же проект.
Под виндой c mingw — ошибок не выдает.
А в линуксе g++ 10.1 — выдает ошибку линкера
pedantic стоит и там, и там.
-Wall стоит и там, и там.
Нетрудно переименовать, чтобы в каждом файле было разное имя.
Но почему разное поведение компилятора ?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Один и тот же проект. LVV>Под виндой c mingw — ошибок не выдает.
vopl@vopl MINGW64 ~/tmp $ cat a.cpp
auto g = []{};
int main(){}
vopl@vopl MINGW64 ~/tmp $ cat b.cpp
auto g = []{};
vopl@vopl MINGW64 ~/tmp $ g++ a.cpp b.cpp
D:/c/opt/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\c\opt\msys64\tmp\ccwWYFsV.o:b.cpp:(.bss+0x0): multiple definition of `g'; D:\c\opt\msys64\tmp\ccQ3Iiqi.o:a.cpp:(.bss+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
LVV>>Нетрудно переименовать, чтобы в каждом файле было разное имя. AD>Может статик или анонимное пространство имен? Зачем он экстерн?
Нет, не статик.
Но анонимное пространство имен — да.
Но код совершенно одинаковый и в винде, и в линуксе.
Я ж и сам удивился, что у меня все собирается без проблем.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>>>Нетрудно переименовать, чтобы в каждом файле было разное имя. AD>>Может статик или анонимное пространство имен? Зачем он экстерн? LVV>Нет, не статик. LVV>Но анонимное пространство имен — да.
LVV>>>>Нетрудно переименовать, чтобы в каждом файле было разное имя. AD>>>Может статик или анонимное пространство имен? Зачем он экстерн? LVV>>Нет, не статик. LVV>>Но анонимное пространство имен — да. AD>Не понял, оно сейчас в анонимном?
Да, все имена объявлены старым дедовским способом.
Просто как глобальные переменные.
Обычные переменные, естественно, с одинаковыми именами
не позволяет в двух разных файлах объявить.
Даже разных типов.
А вот с лямбдами такая получилась засада.
Абсолютно две одинаковые лямбды с одинаковыми именами, объявленные глобально,
mingw кушает, а в линуксе выдает нормально ошибку линкера.
Причем еще и пишет, в каком файле была определена первый раз.
Что и должно быть.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>А вот с лямбдами такая получилась засада. LVV>Абсолютно две одинаковые лямбды с одинаковыми именами, объявленные глобально, LVV>mingw кушает, а в линуксе выдает нормально ошибку линкера.
Можете привести полный код, который под mingw не приводит к ошибке пожалуйста? Весьма интересно как это так
LVV>>>Но почему разное поведение компилятора ? σ>>Потому что стандарт разрешает вести себя как угодно LVV>Это я не совсем понял. LVV>unspecified ?
IFNDR
LVV>Понятно, что компиляция файлов проходит без ошибок
LVV>Но почему все собирается без ошибок?
Так в стандарте. LVV>У лямбд внутреннее связывание, как у констант ?
Нет, но их можно объявить константами. LVV>Или это связано с выводом типов и у них таки разный тип получается ?
Тип разный, но это не столь важно. LVV>Где про это прочитать ?
Нарушение ODR, полагаю. Wiki
Вообще говоря это, наверное, худший из подводных камней C++. В больших проектах невозможно отследить отсутствие пересечений по именам.