c ++ 11 — неуказанный вывод с использованием встроенной функции в переполнении стека

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

test1.cpp

#include<iostream>
using namespace std;
inline int c()
{
static int p=0;
p++;
return p;
}
void a()
{
cout<<"\nIn function a() , c = "<<c();
}

test2.cpp

#include<iostream>
using namespace std;

inline int c()
{
static int p=12;
p++;
return p;
}

void b()
{
cout<<"\nIn function b() , c = "<<c();
}

driver.cpp

#include<iostream>
using namespace std;

void a();
void b();
int c();

int main()
{
b();
a();
a();
b();
cout<<"\nIn function main() = , c "<< c();
cout<<"\n";
}

вывод 1: —

when compiles as follows :-

bash#>g++ -c test1.cpp
bash#>g++ -c test2.cpp
bash#>g++ -c driver.cpp

bash#>g++ -o out driver.o test1.o test2.o
bash#>./out

In function b() , c = 1
In function a() ,  c = 2
In function a() ,  c = 3
In function b() , c = 4
IN main() , c = 5

В приведенном выше выводе компилятор рассматривает c (), определенный в test1.cpp

вывод 2: —
изменение последовательности test1.o и test2.o при компоновке.

bash#>g++ -o out driver.o test2.o test1.o

In function b() , c = 13
In function a() ,  c = 14
In function a() ,  c = 15
In function b() , c = 16
IN main() , c = 17

В приведенном выше выводе компилятор рассматривает c (), определенный в test2.cpp

Я был озадачен, когда я сделал небольшие изменения в коде, а именно:

1) если я не вызову c () в функции a () [test1.cpp] и c () в функции b () [test2.cpp]

//test1.cpp changes
void a()
{
cout<<"\nIn function a() , c = "; // not calling c()
}

//test2.cpp changes
void b()
{
cout<<"\nIn function b() , c = "; // not calling c()
}

Я получаю следующую ошибку при ссылке: —

bash#>g++ -o out driver.o test1.o test2.o
driver.o: In function `main':
driver.cpp:(.text+0x1f): undefined reference to `c()'
collect2: ld returned 1 exit status

2) Если я вызову c () в любом из файлов, т. Е. В test1.cpp или test2.cpp, то я не получу ошибку компоновщика.

Может ли кто-нибудь, пожалуйста, помогите мне в понимании этого поведения.

Заранее спасибо.

1

Решение

Ваша программа имеет неопределенное поведение, потому что она нарушает правило единого определения. Две разные единицы перевода определяют функцию с одинаковым именем и подписью, но с разными телами.

В соответствии с пунктом 3.2 / 6 стандарта C ++ 11:

[…] Дано
такой объект по имени D определено более чем в одной единице перевода, затем

— каждое определение D должен состоять из одинаковой последовательности токенов; а также

[…]

Ваша программа также плохо сформирована, потому что функция c() объявлен как inline в test1.cpp а также test2.cpp, но не в driver.cpp, Согласно пункту 7.1.2 / 4

[…] Если функция с внешней связью
объявленный inline в одной единице перевода это должно быть объявлено inline во всех переводческих единицах, в которых он появляется;
Диагностика не требуется. […]

«Диагностика не требуется«бит» означает, что компилятор (или компоновщик) может сообщать или не сообщать об ошибке за нарушение этого правила. Это означает, что вы должны быть очень осторожны, чтобы его нарушить.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]