<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904997</guid>
        <pubDate>Thu, 30 May 2024 16:41:52 +0000</pubDate>
        <title>Не могу использовать имя &amp;quot;exp&amp;quot; в коде.</title>
        <link>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904997</link>
        <description><![CDATA[Qraizer: Нет, конечно. Компилятор. Когда Стандарт на нарушение говорит, мол, диагностики не требуется, это не означает, что её не должно быть, это означает лишь, что она может отсутствовать.<br>
Я проверил на g++ под убундой, там всё нормально и компилится, и собирается. Типичный пример неопределённого поведения, в разных реализациях может быть по-разному. В частности и ожидаемым образом, как у меня. Но.<br>
Чуть изменим ситуацию:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// f1.cpp</div><div class="code_line">#include &#60;iostream&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">float exp = 1.0;</div><div class="code_line">&nbsp;</div><div class="code_line">float foo(float);</div><div class="code_line">&nbsp;</div><div class="code_line">int main()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;std::cout &#60;&#60; exp &#60;&#60; &#39;\t&#39; &#60;&#60; foo(exp) &#60;&#60; std::endl;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;return 0;</div><div class="code_line">}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// f2.cpp</div><div class="code_line">#include &#60;cmath&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">float foo(float x)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;return exp(x);</div><div class="code_line">}</div></ol></div></div></div></div><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">censored:~/Документы/c++$ g++ f1.cpp f2.cpp</div><div class="code_line">censored:~/Документы/c++$ ./a.out</div><div class="code_line">Ошибка сегментирования (стек памяти сброшен на диск)</div><div class="code_line">censored:~/Документы/c++$</div></ol></div></div></div></div>Нарушение ODR собственной персоной, для которой диагностики не требуется. Но:<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// f2.cpp</div><div class="code_line">#include &#60;cmath&#62;</div><div class="code_line">&nbsp;</div><div class="code_line">float foo(float x)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp;return std::exp(x);</div><div class="code_line">}</div></ol></div></div></div></div><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">censored:~/Документы/c++$ g++ f1.cpp f2.cpp</div><div class="code_line">censored:~/Документы/c++$ ./a.out</div><div class="code_line">1 &nbsp; &nbsp; &nbsp; 2.71828</div><div class="code_line">censored:~/Документы/c++$</div></ol></div></div></div></div> :whistle: Потому что в C не было пространств имён (точнее, они были, но абсолютно в другом смысле), поэтому если в C++ для exp() в глобальном скопе требовалось связывание extern &quot;C&quot; для совместимости с библиотекой C, то внутри namespace std это уже не требуется и даже невозможно, поэтому там используется extern &quot;C++&quot;, что делает символы там и в глобальном скопе для линкера разными.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904996</guid>
        <pubDate>Thu, 30 May 2024 16:15:30 +0000</pubDate>
        <title>Не могу использовать имя &amp;quot;exp&amp;quot; в коде.</title>
        <link>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904996</link>
        <description><![CDATA[macomics: Тогда тут получается ругается линкер?<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">int exp = 1;</div><div class="code_line">&nbsp;</div><div class="code_line">int main(){</div><div class="code_line">&nbsp;&nbsp; &nbsp;return exp;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">$ g++ -o c1.o -c 1.cpp</div><div class="code_line">1.cpp:1:5: предупреждение: built-in function «exp» declared as non-function [-Wbuiltin-declaration-mismatch]</div><div class="code_line">&nbsp;&nbsp; &nbsp;1 | int exp = 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;| &nbsp; &nbsp; ^~~</div></ol></div></div></div></div>Хотя я просто создаю объектный файл без линкера.<br>
<br>
ADD: Хотя, подозреваю, что это gcc так перестраховывается, чтобы предупредить появление подобных ошибок.]]></description>
        <author>macomics</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904995</guid>
        <pubDate>Thu, 30 May 2024 16:04:27 +0000</pubDate>
        <title>Не могу использовать имя &amp;quot;exp&amp;quot; в коде.</title>
        <link>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904995</link>
        <description><![CDATA[riden: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=446248&view=findpost&p=3904987'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Qraizer &#064; <time class="tag-quote__quoted-time" datetime="2024-05-30T14:45:11+00:00">30.05.24, 14:45</time></span><div class='quote '>В библиотеке потоков C++98 был дефект, заключающийся в том, что подключив &lt;iostream&gt;, мы лишь получаем доступ к стандартным потокам, и по сути можем лишь... получить ссылку, например. Элементарный operator&lt;&lt; по-хорошему был недоступен, т.к. он определён в другом заголовке. Т.ч. в дополнение к &lt;iostream&gt; приходилось подключать ещё всякие там &lt;istream&gt; и иже с ним. В C++11 этот дефект был исправлен, т.к. Комитет решил, что &lt;iostream&gt; без этих дополнительных заголовков практически бесполезен, т.ч. теперь стандартизировано, что он включает &lt;istream&gt;, &lt;ostream&gt;, &lt;ios&gt; и &lt;streambuf&gt;. VS именно так и поступает (пусть и несколько окольным путём, как я не поленился посмотреть), но она идёт также немного дальше.<br>
&lt;streambuf&gt; определяет std::basic_streambuf&lt;&gt;, а у него регламентируется поддержка локалей через std::basic_streambuf&lt;&gt;::imbue(). Также Стандарт регламентирует, что не только все методы фасетов константны, но и std::use_facet&lt;&gt; возвращает константные ссылки на фасеты. Стандарт это делает, чтобы гарантировать неизменность национальных особенностей в std::locale после создания его экземпляра, что в общем-то более чем резонно. У потоков в итоге есть прекрасное средство оптимизации: ещё внутри std::basic_streambuf&lt;&gt;::imbue() они могут выполнить все необходимые подготовительные операции для подстройки под новые пользовательские соглашения и предпочтения. Поэтому стандартная библиотека в VS в &lt;streambuf&gt; тянет кучу других заголовков, и т.к. все (почти) фасеты являются шаблонами, ибо зависят от типа символа, которым конкретизируются, char там, или wchar_t, или ещё каким, то и их методы лежат в заголовках (как того требует правила работы с инстанцированием шаблонов вообще и ODR в частности). В итоге в эту кучу входит &lt;cmath&gt;, который нужен std::num_put&lt;&gt; (а может и std::num_get&lt;&gt;). Так &lt;cmath&gt; оказывается косвенно включённым в единицу трансляции, которая подключает &lt;iostream&gt;.<br>
Это был первый вопрос &quot;как так-то?&quot;. Вопрос второй &quot;а имела ли право VS так поступать&quot;. Я пересмотрел Стандарты C++ и C и не обнаружил там ни одного запрета на то, чтобы какой-нибудь стандартный заголовок включал другой заголовок, также из числа стандартных. Так что ответ &quot;да, имела&quot;. Вопрос третий &quot;а насколько это хорошо&quot; уже далеко не так очевиден.<br>
Спервоначалу следует заметить, что Стандарты в один голос утверждают, что использование библиотечных сущностей без предварительного подключения соответствующего заголовка ведёт к неопределённому поведению. Формально символ exp относится к библиотеке C, а не С++, однако библиотека C является частью С++, так что по-любому присутствует в языке и наследует все особенности использования. (При этом символы из глобальной области видимости дублируются в std.) Твой код использует символ exp, но не подключает заголовок &lt;cmath&gt;, в итоге ты имеешь то, что видишь: одно из возможных проявлений неопределённого поведения. Твоё желание использовать именно exp понятно, я сам когда-то ловил грабли с exit, но в итоге плюнул и переименовал её в quit. Не могу не согласиться ни с компилятором, ни со Стандартом, ибо просто взглянув на твой код, я тоже словил &quot;так, стоп&quot; и только через пару секунд сообразил, что ты хотел написать, куда уж тут бездушным кремниевым болванкам. Не ну и правда, что такое exp я знаю, отсутствие подключения &lt;cmath&gt; ещё заметить надо, и заметив, непонятно, где баг: программер то ли набажил с функцией, то ли с заголовком, то ли с присваиванием, то ли вообще не набажил. Я бы даже сказал, что VS правильно поступила, что выругалась ещё при компиляции, предупредив неопределённое поведение. Если б он косвенно не подключил &lt;cmath&gt; при компиляции, могло получиться так, чтоб на множественное определение exp мог выругаться линкер, т.к. предкомпилированная exp() уже лежит в где-нибудь в glibc++.a и тянется вместе с каким-нибуль operator&lt;&lt;. А мог и не выругаться, т.к. это банальное нарушение ODR, для которого не требуется диагностики, в итоге полгода нормально работавшая программа вдруг начинает падать на ровном месте, когда exp понадобилось присвоить новое значение.<br>
Мораль в целом вот: не стоит использовать Стандартные идентификаторы для своих целей.<br>
<br>
Добавлено Сегодня, 17:58<br>
P.S. И да – все символы стандартной библиотеки C находятся в глобальном пространстве имён и в C++ тоже. Причём для этого есть и более веская причина, нежели легаси-код или там удобство. Причина в ADL, без которой нынешний C++ просто не существовал бы, и который пришлось внести в язык ещё в середине 90-ых, т.е. до первого стандарта C++98.</div></div><br>
<br>
Спасибо за подробный ответ.]]></description>
        <author>riden</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904987</guid>
        <pubDate>Thu, 30 May 2024 14:45:11 +0000</pubDate>
        <title>Не могу использовать имя &amp;quot;exp&amp;quot; в коде.</title>
        <link>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904987</link>
        <description><![CDATA[Qraizer: В библиотеке потоков C++98 был дефект, заключающийся в том, что подключив &lt;iostream&gt;, мы лишь получаем доступ к стандартным потокам, и по сути можем лишь... получить ссылку, например. Элементарный operator&lt;&lt; по-хорошему был недоступен, т.к. он определён в другом заголовке. Т.ч. в дополнение к &lt;iostream&gt; приходилось подключать ещё всякие там &lt;istream&gt; и иже с ним. В C++11 этот дефект был исправлен, т.к. Комитет решил, что &lt;iostream&gt; без этих дополнительных заголовков практически бесполезен, т.ч. теперь стандартизировано, что он включает &lt;istream&gt;, &lt;ostream&gt;, &lt;ios&gt; и &lt;streambuf&gt;. VS именно так и поступает (пусть и несколько окольным путём, как я не поленился посмотреть), но она идёт также немного дальше.<br>
&lt;streambuf&gt; определяет std::basic_streambuf&lt;&gt;, а у него регламентируется поддержка локалей через std::basic_streambuf&lt;&gt;::imbue(). Также Стандарт регламентирует, что не только все методы фасетов константны, но и std::use_facet&lt;&gt; возвращает константные ссылки на фасеты. Стандарт это делает, чтобы гарантировать неизменность национальных особенностей в std::locale после создания его экземпляра, что в общем-то более чем резонно. У потоков в итоге есть прекрасное средство оптимизации: ещё внутри std::basic_streambuf&lt;&gt;::imbue() они могут выполнить все необходимые подготовительные операции для подстройки под новые пользовательские соглашения и предпочтения. Поэтому стандартная библиотека в VS в &lt;streambuf&gt; тянет кучу других заголовков, и т.к. все (почти) фасеты являются шаблонами, ибо зависят от типа символа, которым конкретизируются, char там, или wchar_t, или ещё каким, то и их методы лежат в заголовках (как того требует правила работы с инстанцированием шаблонов вообще и ODR в частности). В итоге в эту кучу входит &lt;cmath&gt;, который нужен std::num_put&lt;&gt; (а может и std::num_get&lt;&gt;). Так &lt;cmath&gt; оказывается косвенно включённым в единицу трансляции, которая подключает &lt;iostream&gt;.<br>
Это был первый вопрос &quot;как так-то?&quot;. Вопрос второй &quot;а имела ли право VS так поступать&quot;. Я пересмотрел Стандарты C++ и C и не обнаружил там ни одного запрета на то, чтобы какой-нибудь стандартный заголовок включал другой заголовок, также из числа стандартных. Так что ответ &quot;да, имела&quot;. Вопрос третий &quot;а насколько это хорошо&quot; уже далеко не так очевиден.<br>
Спервоначалу следует заметить, что Стандарты в один голос утверждают, что использование библиотечных сущностей без предварительного подключения соответствующего заголовка ведёт к неопределённому поведению. Формально символ exp относится к библиотеке C, а не С++, однако библиотека C является частью С++, так что по-любому присутствует в языке и наследует все особенности использования. (При этом символы из глобальной области видимости дублируются в std.) Твой код использует символ exp, но не подключает заголовок &lt;cmath&gt;, в итоге ты имеешь то, что видишь: одно из возможных проявлений неопределённого поведения. Твоё желание использовать именно exp понятно, я сам когда-то ловил грабли с exit, но в итоге плюнул и переименовал её в quit. Не могу не согласиться ни с компилятором, ни со Стандартом, ибо просто взглянув на твой код, я тоже словил &quot;так, стоп&quot; и только через пару секунд сообразил, что ты хотел написать, куда уж тут бездушным кремниевым болванкам. Не ну и правда, что такое exp я знаю, отсутствие подключения &lt;cmath&gt; ещё заметить надо, и заметив, непонятно, где баг: программер то ли набажил с функцией, то ли с заголовком, то ли с присваиванием, то ли вообще не набажил. Я бы даже сказал, что VS правильно поступила, что выругалась ещё при компиляции, предупредив неопределённое поведение. Если б он косвенно не подключил &lt;cmath&gt;  при компиляции, могло получиться так, чтоб на множественное определение exp мог выругаться линкер, т.к. предкомпилированная exp() уже лежит в где-нибудь в glibc++.a и тянется вместе с каким-нибуль operator&lt;&lt;. А мог и не выругаться, т.к. это банальное нарушение ODR, для которого не требуется диагностики, в итоге полгода нормально работавшая программа вдруг начинает падать на ровном месте, когда exp понадобилось присвоить новое значение.<br>
Мораль в целом вот: не стоит использовать Стандартные идентификаторы для своих целей. <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2024-05-30T14:58:20+00:00">30.05.24, 14:58</time></span></span><br>
P.S. И да – все символы стандартной библиотеки C находятся в глобальном пространстве имён и в C++ тоже. Причём для этого есть и более веская причина, нежели легаси-код или там удобство. Причина в ADL, без которой нынешний C++ просто не существовал бы, и который пришлось внести в язык ещё в середине 90-ых, т.е. до первого стандарта C++98.]]></description>
        <author>Qraizer</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904985</guid>
        <pubDate>Thu, 30 May 2024 13:22:30 +0000</pubDate>
        <title>Не могу использовать имя &amp;quot;exp&amp;quot; в коде.</title>
        <link>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904985</link>
        <description><![CDATA[riden: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=446248&view=findpost&p=3904934'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>macomics &#064; <time class="tag-quote__quoted-time" datetime="2024-05-30T02:23:24+00:00">30.05.24, 02:23</time></span><div class='quote '>А exp это разве не встроенная функция. Она должна быть доступна вообще без подключения модулей. Наличие #include &lt;iostream&gt; тут не причем</div></div><br>
Нет. Это библиотечная функция (стандартная библиотека) из модуля (заголовочного файла) про математику. И для меня странно её попадание в код посредством заголовочного файла для ввода-вывода, и еще страннее её доступность без пространства имён std. <strong class='tag-b'>Зачем такое делать???</strong>]]></description>
        <author>riden</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904934</guid>
        <pubDate>Thu, 30 May 2024 02:23:24 +0000</pubDate>
        <title>Не могу использовать имя &amp;quot;exp&amp;quot; в коде.</title>
        <link>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904934</link>
        <description><![CDATA[macomics: А exp это разве не встроенная функция. Она должна быть доступна вообще без подключения модулей. Наличие #include &lt;iostream&gt; тут не причем.]]></description>
        <author>macomics</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904933</guid>
        <pubDate>Wed, 29 May 2024 19:05:22 +0000</pubDate>
        <title>Не могу использовать имя &amp;quot;exp&amp;quot; в коде.</title>
        <link>https://forum.sources.ru/index.php?showtopic=446248&amp;view=findpost&amp;p=3904933</link>
        <description><![CDATA[riden: Visual Studio 2022, C++20.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">#include &#60;iostream&#62;</div><div class="code_line">float exp = 1.0; //Error C2365 &#39;exp&#39;: redefinition; previous definition was &#39;function&#39;</div><div class="code_line">&nbsp;</div><div class="code_line">int main(){</div><div class="code_line">&nbsp;&nbsp; &nbsp;std::cout&#60;&#60;exp&#60;&#60;std::endl;</div><div class="code_line">&nbsp;&nbsp; &nbsp;return 0;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>Поражает, что я не подключаю cmath и т.п., не подключаю пространство имён std</strong>. И всё равно возникает такая херня&#33;<br>
<br>
Я хочу использовать имя &quot;exp&quot; не отказываясь от подключения заголовочного файла &lt;iostream&gt; и не помещая своё exp в какое-либо пространство имён.]]></description>
        <author>riden</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	