embeded/Cortex-M4 Ti2018. 4. 20. 09:39

예전에도 찾았다가 해결은 못한거 같은데

일단 간단하게 결론만 말하자면


__inline 대신에

estern __inline으로 선언하면 해결된다.

(__inline에서 호출되는 변수/함수들에 static이 되어있으면

이걸 다 따라가서 static 없애는 것 보다는 옳은 방향으로 보임)



error:  #1059-D: an entity with internal linkage cannot be referenced within an inline function with external linkage


internal linkage

internal linkage를 가지는 이름은 외부 translation unit으로 공개되지 않는다. internal linkage를 가지는 이름은 다음과 같다.


namespace scope에 선언된 static specifier가 붙은 이름

namespace scope에 선언된 anonymous union의 데이터 멤버

namespace scope에 선언된 const 혹은 constexpr이 붙고 volatile은 아닌 변수

unnamed namespace에 선언된 모든 이름



external linkage

 위에서 설명한 internal linkage와 다르게 external linkage를 가지는 이름은 다른 translation unit과 공유된다. 다시 말해서 어떤 이름이 external linkage를 가진다면 그 이름은 서로 다른 translation unit에서 사용되더라도 같은 내용을 가져야 한다.


namespace scoep에 선언 된 이름 중 internal linkage가 아닌 이름.

block scope에 선언된 함수

block scope에 선언된 변수 중에서 extern으로 선언된 변수 

[링크 : https://blog.seulgi.kim/2017/08/cpp-linkage.html]


Internal Linkage: An identifier implementing internal linkage is not accessible outside the translation unit it is declared in. Any identifier within the unit can access an identifier having internal linkage. It is implemented by the keyword static. An internally linked identifier is stored in initialized or uninitialized segment of RAM.  


External Linkage: An identifier implementing external linkage is visible to every translation unit. Externally linked identifiers are shared between translation units and are considered to be located at the outermost level of the program. In practice, this means that you must define an identifier in a place which is visible to all, such that it has only one visible definition. It is the default linkage for globally scoped variables and functions. Thus, all instances of a particular identifier with external linkage refer to the same identifier in the program. The keyword extern implements external linkage.

When we use the keyword extern, we tell the linker to look for the definition elsewhere. Thus, the declaration of an externally linked identifier does not take up any space. Extern identifiers are generally stored in initialized/uninitialized or text segment of RAM. If uninitialized, the value of the identifier is set to 0 by the kernel.

[링크 : https://www.geeksforgeeks.org/internal-linkage-external-linkage-c/]


That looks perfectly fine under the C99 rules. Because stack.c is compiled with both an extern and inline declaration of the function, it will be defined with external linkage and can also be inlined within that file.


Other files will have only the declaration, and so will link to the version with external linkage.


Note that the function isn't allowed to define any modifiable objects with static storage duration, or reference any functions or global variables that aren't extern. 

[링크 : https://stackoverflow.com/.../how-to-define-a-function-to-be-inline-internal-and-external-copy-in-c99]


If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function, and had not defined it.


This combination of inline and extern has almost the effect of a macro. The way to use it is to put a function definition in a header file with these keywords, and put another copy of the definition (lacking inline and extern) in a library file. The definition in the header file causes most calls to the function to be inlined. If any uses of the function remain, they refer to the single copy in the library. 

[링크 : https://gcc.gnu.org/onlinedocs/gcc/Inline.html]


C99 inline semantics are often misunderstood. The inline specifier serves two purposes:


First, as a compiler hint in case of static inline and extern inline declarations. Semantics remain unchanged if you remove the specifier.


Second, in case of raw inline (ie without static or extern) to provide an inline definition as an alternative to an external one, which has to be present in a different translation unit. Not providing the external one is undefined behaviour, which will normally manifest as linking failure.

[링크 : https://stackoverflow.com/questions/16245521/c99-inline-function-in-c-file]


translation unit은 C++ compilation의 기본 단위입니다. <소스 파일 하나 + 직접/간접적으로 include된 헤더파일의 내용물(전처리기 조건에 따라 몇몇은 무시)>로 구성되어 있습니다.


translation unit 한개는 object file, library나 실행가능한 프로그램으로 컴파일 될 수 있습니다. 

[링크 : http://hashcode.co.kr/questions/1244/translation-unit에-대해서]


A translation unit is the basic unit of compilation in C++. It consists of the contents of a single source file, plus the contents of any header files directly or indirectly included by it, minus those lines that were ignored using conditional preprocessing statements.


A single translation unit can be compiled into an object file, library, or executable program.


The notion of a translation unit is most often mentioned in the contexts of the One Definition Rule, and templates. 

[링크 : https://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c]


2016/04/12 - [embeded/Cortex-M4 Ti] - keil/c99 에서 __inline ...?


Posted by 구차니