可以使用内联命名空间来保持共享库中的向后兼容性? [英] Can inline namespaces be used to keep backwards compatibility in a shared library?
问题描述
(有关更多信息和源兼容性示例,请参阅 this question )
(解决相关问题,使用内联命名空间引入不兼容性,请参阅这个问题)
如果这是我们当前的库(例如mylib.dll),它是与客户共享的,需要稳定:
struct ModelA
{
/ *(...)很多东西* /
};
struct ModelB
{
/ *(...)很多东西* /
};我们可以使用内联命名空间来引入结构体/类的新版本,而不会破坏客户端(例如,替换成一个新的结构体)。
<
inline命名空间mylib
{
inline namespace v1
{
struct ModelA
{
/ *(...)很多东西* /
};
} // end namespace v1
namespace v2
{
struct ModelA
{
/ *(...) + newstuff * /
};
} // end namespace v2
struct ModelB
{
/ *(...)很多东西* /
};
} // end namespace mylib
如果没有,包含的内联命名空间mylib?
不是真正的答案,但可能会导致一个答案。 >
在 gcc 4.8.2
下测试两个简单来源:
命名空间n1
{
void f1(int);
inline命名空间n2
{
void f2(int);
}
}
void f(int x)
{
n1 :: f1(x);
n1 :: f2(x);
}
没有inline命名空间:
命名空间n1
{
void f1(int);
void f2(int);
}
void f(int x)
{
n1 :: f1(x);
n1 :: f2(x);
}
然后使用 objdump -t
。
第一个版本的结果(与 inline命名空间):
_ZN2n12f1Ei
_ZN2n12n22f2Ei
$ b b
第二版本(无内联命名空间):
_ZN2n12f1Ei
_ZN2n12f2Ei
您可以看到 f2
不同(第一个包括 n2
命名空间的名称)。这意味着如果你使用 gcc
,你不能只是用一个带有内联命名空间的新库来替换你的库。我不会指望一些其他编译器会做另一种方式(保存二进制兼容内联命名空间)。
The rationale for C++'s inline namespaces is both source and binary compatibility (see Herb Sutter's paper linked in N2535), but I have not been able to find good examples of keeping binary compatibility for existing libraries when introducing inline namespaces, or if it is possible.
(for more info, and examples of source compatibility, see this question)
(for solving a related problem, using inline namespace to introduce incompability, see this question)
If this is our current library (e.g. mylib.dll), which is shared with clients and need to be stable:
struct ModelA
{
/* (...) lots of stuff */
};
struct ModelB
{
/* (...) lots of stuff */
};
Can we use inline namespaces to introduce new versions of the structs/classes without breaking the clients (i.e. replace the shared library file (mylib.dll) only, no recompile neccessary)?
inline namespace mylib
{
inline namespace v1
{
struct ModelA
{
/* (...) lots of stuff */
};
} // end namespace v1
namespace v2
{
struct ModelA
{
/* (...) lots of stuff + newstuff */
};
} // end namespace v2
struct ModelB
{
/* (...) lots of stuff */
};
} // end namespace mylib
If not, will it work without the enclosing inline namespace mylib?
Not really an answer to your question, but probably can lead to an answer.
Tested under gcc 4.8.2
with two simple sources:
namespace n1
{
void f1 (int);
inline namespace n2
{
void f2 (int);
}
}
void f (int x)
{
n1::f1(x);
n1::f2(x);
}
And without inline namespace:
namespace n1
{
void f1 (int);
void f2 (int);
}
void f (int x)
{
n1::f1(x);
n1::f2(x);
}
Then inspected mangled names of symbols in compiled object files using objdump -t
.
Results for the first version (with inline namespace):
_ZN2n12f1Ei
_ZN2n12n22f2Ei
Second version (without inline namespace):
_ZN2n12f1Ei
_ZN2n12f2Ei
You can see that the mangled name of f2
differs (the first one includes the name of n2
namespace). It means that in case you are using gcc
, you cannot just replace your library with a new one with inlined namespaces. I won't expect that some other compiler will do it another way (save binary compatibility with inline namespaces).
这篇关于可以使用内联命名空间来保持共享库中的向后兼容性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!