这是什么意思的名称或键入有一定的语言联动? [英] What does mean for a name or type to have a certain language linkage?

查看:294
本文介绍了这是什么意思的名称或键入有一定的语言联动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据(三)ANSI ISO / IEC 14882:2003,第127页:


  

联动规格窝。当联动规格窝,最里面的那个决定语言。链接规范没有建立一个范围。的连锁规格,应仅在命名空间范围(3.3)发生。在联动规范,指定的语言联动适用于由该声明(S)推出的函数类型的所有函数声明,函数名和变量名的。


 的externC无效F1(无效(* PF)(INT));
//名f1和它的功能型有C语言
//联动; PF是一个指向C函数为externC无效的typedef FUNC();
FUNC F2;
//名称F2具有C ++语言的联动和
//函数的类型有C语言联动为externCFUNC F3;
//函数f3的名称和功能的类型
//有C语言联动无效(* PF2)(FUNC *);
//变量PF2的名称有C ++和联动
// PF2的类型是指针的C ++函数
//采用指针类型的一个参数C函数

这是什么意思呢?例如,有什么不联动的 F2()功能都有,C或C ++语言的联系?

正如@Johannes绍布指出,有一种这意味着什么标准,因此可以在不同的编译器是跨preTED不同没有真正的解释。

请解释在目标文件中的差异:


  • 函数的C语言联动和C ++语言的链接名称。

  • 函数的C语言联动和C ++语言的链接类型。


解决方案

语言联动是 C ++ 非C之间用于联系的术语++ code片段。通常,在C ++程序,所有的函数名,函数类型,甚至变量名都默认的C ++语言的联系。

一个C ++对象code可以链接到这是使用其他来源的语言使用$ P $生产(如 C ),另一个对象code pdefined联动符。

你必须知道名称重整概念,其中EN codeS函数名,函数类型和变量名,从而生成一个唯一的名称他们。这允许接头的通用名称区分(如在函数重载的情况下)。连接C模块的时候库或对象与C ++编译器编译后的文件名称重整是不可取的。以prevent名字改编为这样的情况下,使用联动符。在这种情况下,的externC是连接符。让我们举个例子(C ++ code提到这里):

 的typedef INT(* pfun)(INT); // 1号线
为externC无效美孚(pfun); // 2号线
为externCINT克(INT)// 3号线
...
富(G); //错误! // 5号线

1号线声明 pfun 来指向一个C ++函数,因为它缺少一个联动符。

2号线,因此声明富是一个C函数,它指向一个C ++函数。

5号线尝试调用foo的指针克,C函数,类型不匹配。

不同的函数名称链接:

让我们以两个不同的文件:

一个用的externC联动(file1.cpp):

 的#include<&iostream的GT;
使用命名空间std;为externC
{
无效美孚(INT A,INT B)
{
    COUT<< 这里;
}
}诠释的main()
{
    富(10,20);
    返回0;
}

一个没有的externC联动(file2.cpp):

 的#include<&iostream的GT;
使用命名空间std;无效美孚(INT A,INT B)
{
    COUT<< 这里;
}诠释的main()
{
    富(10,20);
    返回0;
}

现在编译这两个检查objdump的。

 #G ++ file1.cpp -o文件1
#objdump的-Dx文件1#G ++ file2.cpp -o文件2
#objdump的-Dx文件2

使用的externC键,没有名称重整函数。因此,它正在使用的任何程序(假设我们做一个共享库出来的),可以直接调用foo(其辅助功能,如则dlsym 的dlopen )与出考虑任何名称重整的影响。

  0000000000400774<富计算值:
  400774:55推%RBP
  400775:48 89 E5 MOV%RSP,RBP%
....
....
  400791:C9 leaveq
  400792:C3 retq0000000000400793<主计算值:
  400793:55推%RBP
  400794:48 89 E5 MOV%RSP,RBP%
  400797:为14 00 00 00 $ MOV 0x14的,ESI%
  40079c:BF 0A 00 00 00 $ MOV是0xA,%EDI
  4007a1:E8 CE FF FF FF callq 400774<富>
  4007a6:B8 00 00 00 00 $ MOV为0x0,%eax中
  4007ab:C9 leaveq

在另一方面,当没有的externC正在被使用,FUNC:的错位与(使用已知的编译器/连接器)的一些predefined规则,因此应用程序不能直接从中调用它指定名称为。但是,您可以使用,如果你想的重整名称( _Z3fooii 在这种情况下)调用它,但没有人使用它的明显的原因。

  0000000000400774< _Z3fooii计算值:
  400774:55推%RBP
  400775:48 89 E5 MOV%RSP,RBP%
 ...
...
  400791:C9 leaveq
  400792:C3 retq0000000000400793<主计算值:
  400793:55推%RBP
  400794:48 89 E5 MOV%RSP,RBP%
  400797:为14 00 00 00 $ MOV 0x14的,ESI%
  40079c:BF 0A 00 00 00 $ MOV是0xA,%EDI
  4007a1:E8 CE FF FF FF callq 400774< _Z3fooii>
  4007a6:B8 00 00 00 00 $ MOV为0x0,%eax中
  4007ab:C9 leaveq
  4007ac:C3 retq

此页面也是这个特定主题的很好看的。

一个很好的和明确的解释文章关于调用约定:<一href=\"http://www.$c$cproject.com/KB/cpp/calling_conventions_demystified.aspx\">http://www.$c$cproject.com/KB/cpp/calling_conventions_demystified.aspx

According to (c) ANSI ISO/IEC 14882:2003, page 127:

Linkage specifications nest. When linkage specifications nest, the innermost one determines the language. A linkage specification does not establish a scope. A linkage-specification shall occur only in namespace scope (3.3). In a linkage-specification, the specified language linkage applies to the function types of all function declarators, function names, and variable names introduced by the declaration(s).

extern "C" void f1(void(*pf)(int));
// the name f1 and its function type have C language
// linkage; pf is a pointer to a C function

extern "C" typedef void FUNC();
FUNC f2;
// the name f2 has C++ language linkage and the
// function's type has C language linkage

extern "C" FUNC f3;
// the name of function f3 and the function's type
// have C language linkage

void (*pf2)(FUNC*);
// the name of the variable pf2 has C++ linkage and
// the type of pf2 is pointer to C++ function that
// takes one parameter of type pointer to C function

What does all this mean? For example, what linkage does the f2() function have, C or C++ language linkage?

As pointed out by @Johannes Schaub, there is no real explanation of what this means in the Standard so it can be interpreted differently in different compilers.

Please explain the differences in the object file:

  • a function's name with C language linkage and C++ language linkage.
  • a function's type with C language linkage and C++ language linkage.

解决方案

Language linkage is the term used for linkage between C++ and non-C++ code fragments. Typically, in a C++ program, all function names, function types and even variable names have the default C++ language linkage.

A C++ object code can be linked to another object code which is produced using some other source language (like C) using a predefined linkage specifier.

As you must be aware of the concept of name mangling, which encodes function names, function types and variable names so as to generate a unique name for them. This allows the linker to differentiate between common names (as in the case of function overloading). Name mangling is not desirable when linking C modules with libraries or object files compiled with a C++ compiler. To prevent name mangling for such cases, linkage specifiers are used. In this case, extern "C" is the linkage specifier. Let's take an example (c++ code mentioned here):

typedef int (*pfun)(int);  // line 1
extern "C" void foo(pfun); // line 2
extern "C" int g(int)      // line 3
...
foo( g ); // Error!        // line 5

Line 1 declares pfun to point to a C++ function, because it lacks a linkage specifier.

Line 2 therefore declares foo to be a C function that takes a pointer to a C++ function.

Line 5 attempts to call foo with a pointer to g, a C function, a type mis-match.

Diff in function name linkage:

Let's take two different files:

One with extern "c" linkage (file1.cpp):

#include <iostream>
using namespace std;

extern "C"
{
void foo (int a, int b)
{
    cout << "here";
}
}

int main ()
{
    foo (10,20);
    return 0;
}

One without extern "c" linkage (file2.cpp):

#include <iostream>
using namespace std;

void foo (int a, int b)
{
    cout << "here";
}

int main ()
{
    foo (10,20);
    return 0;
}

Now compile these two and check the objdump.

# g++ file1.cpp -o file1
# objdump -Dx file1

# g++ file2.cpp -o file2
# objdump -Dx file2

With extern "C" linkage, there is no name mangling for the function foo. So any program that is using it (assuming we make a shared lib out of it) can directly call foo (with helper functions like dlsym and dlopen) with out considering any name mangling effects.

0000000000400774 <foo>:
  400774:   55                      push   %rbp
  400775:   48 89 e5                mov    %rsp,%rbp
....
....
  400791:   c9                      leaveq 
  400792:   c3                      retq   

0000000000400793 <main>:
  400793:   55                      push   %rbp
  400794:   48 89 e5                mov    %rsp,%rbp
  400797:   be 14 00 00 00          mov    $0x14,%esi
  40079c:   bf 0a 00 00 00          mov    $0xa,%edi
  4007a1:   e8 ce ff ff ff          callq  400774 <foo>
  4007a6:   b8 00 00 00 00          mov    $0x0,%eax
  4007ab:   c9                      leaveq 

On the other hand, when no extern "C" is being used, func: foo is mangled with some predefined rules (known to compiler/linker being used) and so an application can not directly call it from it specifying the name as foo. You can however call it with the mangled name (_Z3fooii in this case) if you want, but nobody use it for the obvious reason.

0000000000400774 <_Z3fooii>:
  400774:   55                      push   %rbp
  400775:   48 89 e5                mov    %rsp,%rbp
 ...
...
  400791:   c9                      leaveq 
  400792:   c3                      retq   

0000000000400793 <main>:
  400793:   55                      push   %rbp
  400794:   48 89 e5                mov    %rsp,%rbp
  400797:   be 14 00 00 00          mov    $0x14,%esi
  40079c:   bf 0a 00 00 00          mov    $0xa,%edi
  4007a1:   e8 ce ff ff ff          callq  400774 <_Z3fooii>
  4007a6:   b8 00 00 00 00          mov    $0x0,%eax
  4007ab:   c9                      leaveq 
  4007ac:   c3                      retq   

This page is also a good read for this particular topic.

A nice and clearly explained article about calling convention: http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx

这篇关于这是什么意思的名称或键入有一定的语言联动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆