Feature #5199
closedD-Pointer
0%
Description
Wt headers include many std headers and wt classes aggregate standard objects by making them thier members. That causes several issues.
1) I have got lots of compile time warnings like that
E:\Develop\Wt\Wt-3.3.6-rc2-msvs2015-Windows-x86-SDK\include\Wt\WObject:531: warning: C4251: Wt::WObject::name_: class "std::basic_string<char,std::char_traits,std::allocator>" needs to have dll-interface to be used by clients of class "Wt::WObject"
2) My IDE code model appears to be slow, when there are different standard library files in scope.
There is a nice qt article describing d-pointer design benefits.
https://wiki.qt.io/D-Pointer
I have also found this :)
https://sourceforge.net/p/witty/mailman/message/2101920/
Is it possible that someday we shall see Wt using d-pointer approach?
Updated by Wim Dumon over 8 years ago
- Status changed from New to Resolved
Hey Vasily,
About (1), will that solve the issue? As far as I understand this warning, a public API function returing an std::string will also cause C4251, I don't think it has only to do with the member variables? A long time ago I concluded this warning was nonsenical and should simply be ignored. I haven't found a method to solve this warning, if the d-pointer/pimpl approach would solve it, it's another reason to consider it. Pimpl has pros and cons...
About (2), I think the use of boost in the public API is the main reason for the large total size of included header files per cpp file. We're working on Wt 4, where we migrate the API to the new standard C constructs that became available in C++11-17, with the aim to eliminate boost from Wt's public API. This has a big impact on compile speed, and likely also on this issue.
Wim.
Updated by Vasily Pupkin over 8 years ago
Hi Wim,
1) C4251 is about object size one exports. If some class, say Wt::WString has std::string member, it's size and member's offsets depend on std::string size. However, it is okay to return std::string as it would be located on the stack and the whole operation will be delegated to standard library .dll or .so. The other way to solve this is to export instanciations of used standard templates:
http://stackoverflow.com/questions/16419318/one-way-of-eliminating-c4251-warning-when-using-stl-classes-in-the-dll-interface
https://support.microsoft.com/en-us/kb/168958 .
2) You are right. Std is not as heavy as boost from this point of view. I can actualy see that boost headers are parsed much slower just because of size as they also include std.
Updated by Vasily Pupkin over 8 years ago
Vasily Pupkin wrote:
Hi Wim,
1) C4251 is about object size one exports. If some class, say Wt::WString, has std::string member, it's size and member's offsets depend on std::string size. However, it is okay to return std::string as it would be located on the stack and the whole operation will be delegated to standard library .dll or .so. The other way to solve this is to export instanciations of used standard templates:
http://stackoverflow.com/questions/16419318/one-way-of-eliminating-c4251-warning-when-using-stl-classes-in-the-dll-interface
https://support.microsoft.com/en-us/kb/168958 .2) You are right. Std is not as heavy as boost from this point of view. I can actualy see that boost headers are parsed much slower just because of size as they also include std.
Updated by Wim Dumon over 8 years ago
Vasily,
I'm probably going off-topic here. In my understanding, a C program using a C library will only work if both the program and the library agree on the object size and layout of the objects being passed between them. To that effect, when using MSVS, you'll have to use the same version of the compiler and runtime library in order to exchange objects between the .exe and .dll. The debug settings also affect object size. And indeed, this also applies to member variables, but just as well to objects passed by value (stack allocation would be different), and objects passed by pointer that were created in the .exe and are also used in the .dll (or the other way around). All of this works properly if your dll and exe are compiled with the same version of msvs, none of this works if your dll and exe are compiled with different versions of the dll. So I'm not sure if C4251 is about object size on exports, object sizes are defined by header files. Exports define what symbols are accessible in DLLs, as far as I know object sizes are not in the export tables. As such, I don't see how exporting STL classes would resolve any problem with sizes of objects.
With respect to C4251, I can assume that an inline method of class X calling a non-inline method of member class Y would cause a link error if class Y is not exported, and the symbols of Y are not available when linking your executable. But for STL classes, this cannot happen, since the CRT is always available.
Which leads me back to my original conclusion: this warning is non-sensical for STL classes.
Disclaimer: I only try to understand dlls and linkages, some of my assumptions may be wrong.
Updated by Vasily Pupkin over 8 years ago
Everything you say is mostly correct. But i am still able to use a library that depends on another version of compiler and std library if i define the interface in the right way. It could be pure C interface. Or an interface that exports only built in types, size of which also doesnt depend on std or whatever.
However, C4251 applied to stl templates seems to be a nonsense to me. But i think there's might be a problem, actualy.
One may think that std is std. And if you have a header file you know everything about imported classes. But for the compiler options that can affect inline methods definitions that manipulate object's data!! This is the only thing that comes to my mind to explain C4251 when aggregating stl. So if i am not mistaken, it is better to hide those aggregations away from public interface.
https://msdn.microsoft.com/en-us/library/esew7y1w.aspx
Looking forward to anyone proving me wrong.
Best wishes.
Updated by Roel Standaert over 7 years ago
- Status changed from Resolved to Closed