Middle+
82
questionbank

Что такое ODR (One Definition Rule) в C++?

Получайте ответы на вопросы в реальном времени с Sobes Copilot
Ответ от нейросети sobes.tech

Пра­ви­ло од­но­го оп­ре­де­ле­ния (One Definition Rule, ODR) тре­бу­ет, что­бы в про­грам­ме каж­дая су­щ­ность (функ­ция, пе­ре­мен­ная, класс, пе­ре­чис­ле­ние, шаб­лон и т.д.), име­ю­щая внеш­нее свя­зы­ва­ние (external linkage) или не име­ю­щая свя­зы­ва­ния (no linkage), бы­ла оп­ре­де­ле­на ров­но один раз. Име­ю­щие внут­рен­нее свя­зы­ва­ние (internal linkage) или ло­каль­ные пе­ре­мен­ные мо­гут оп­ре­де­лять­ся в каж­дой еди­ни­це пре­об­ра­зо­ва­ния (translation unit).

Осо­бые слу­чаи для ODR:

  • Встраиваемые фу­нк­ции и пе­ре­мен­ные (inline functions and variables): Мо­гут оп­ре­де­лять­ся в не­сколь­ких еди­ни­цах пре­об­ра­зо­ва­ния, но все их оп­ре­де­ле­ния дол­ж­ны быть иден­тич­ны с то­ч­ки зре­ния то­ке­нов (token by token).
  • Шаб­ло­ны (templates): Оп­ре­де­ле­ния шаб­ло­нов (функ­ций, клас­сов, пе­ре­мен­ных, али­а­сов) мо­гут при­сут­ст­во­вать в не­сколь­ких еди­ни­цах пре­об­ра­зо­ва­ния там, где они яв­но или не­яв­но ин­стан­циру­ют­ся. Все та­кие оп­ре­де­ле­ния дол­ж­ны быть иден­тич­ны.
  • Ти­пы с раз­ным пред­став­ле­ни­ем (types with different representations): На­ру­ше­ние ODR мо­жет при­ве­с­ти к не­о­п­ре­де­лен­но­му по­ве­де­нию, ес­ли об­щая су­щ­ность (на­при­мер, класс) оп­ре­де­ле­на по-раз­но­му в раз­ных еди­ни­цах пре­об­ра­зо­ва­ния.

При­ме­ры ODR:

На­ру­ше­ния ODR:

cpp
cpp

Со­от­ве­тс­твие ODR:

cpp
cpp

На­ру­ше­ние ODR ча­с­то при­во­дит к ошиб­кам ком­по­нов­ки (linker errors) или, что ху­же, к не­о­п­ре­де­лен­но­му по­ве­де­нию во вре­мя вы­пол­не­ния.