C++/CLI error C1189 when I Include marshal library - c++-cli

I've got a application that is communicating with a PLC.
I have some libraries included for the communication but when I add marshal:
#include <msclr\marshal_cppstd.h>
it gives me the following error:
C1189: #error: The C++ Standard Library forbids macroizing keywords. Enable warning C4005 to find the forbidden macros.
C4005: 'inline': macro redefinition
this C4005 warning shows in
xkeycheck.h line 203 which contains:
#define inline EMIT WARNING C4005
and I get a ton more of errors(1800+).
So what does this error mean?

inline is a C++ keyword which this #define is re-defining. It's warning you that it's pretty risky to change the meaning of inline.
msclr\marshal_cppstd.h has functions marked with inline so this is probably the first occurrence of code using the re-defined inline definition and it's realizing that it is probably not what you're expecting.
I would question why xkeycheck.h is redefining inline -- perhaps inlining is not allowed with their library? Perhaps you need to push/pop the definition of inline around your include or #undef inline before your include?
Update: Did more research, I was assuming xkeycheck was from the PLC code. It's not. So, xkeycheck is set up to report this error if it sees that you've redefine any of the C++ keywords. inline in this case. As I said above, marshal_cppstd.h actually uses inline so that's the first sign of trouble and it's emitting the warning. So.... my advice is to search all your code and find out where you or a header you include has #define'd inline to something else.
I would put the cursor on inline and press F12 to go to the definition.

Related

Is it possible to prevent POSIX symbol name pollution in Objective-C?

I've run into a somewhat unexpected behavior in Xcode/Objective-C. I know it's probably not advised, but if I want to make my own struct in_addr in a .m file, it seems I can't. This implies something rather strange about namespaces and symbol pollution in Objective-C. The same seems to apply for many other networking types and perhaps other POSIX-y things as well.
I came up with a very basic example that demonstrates this behavior. Note that this snippet is the entire contents of the .m file.
#define _SYS_SOCKET_H_
#define _NETINET_IN_H_
#include <stdint.h>
struct in_addr {
uint32_t foo;
};
which yields the build error Redefinition of 'in_addr'.
This implies some fairly strange things about Objective-C. For starters, I wouldn't expect <stdint.h> to bring in any networking types. But even allowing that it might, defining _NETINET_IN_H_ first should prevent the definition of struct in_addr. And yet even still, this code refuses to build.
Is it possible to somehow forgo this forced symbol visibility? Is there a list of symbols that are included, no matter what? Is there a good reason for this behavior?
edit: Stranger still, if i remove <stdint.h> and change the uint32_t to int, this actually does compile.
If you go into the Report navigator and read the full error emitted by the clang tool, you'll see a big hint:
In module 'Darwin' imported from /Users/csrstka/Desktop/asdfasdf/asdfasdf/main.m:1:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/netinet/in.h:302:12: note: field has name 's_addr' here
in_addr_t s_addr;
As you can see, the existing in_addr is coming from the Darwin module, which is implicitly imported due to your #include of stdint.h, which is part of the Darwin module. You can see this if you go to Product > Perform Action > Preprocess in Xcode—instead of copying in all the headers you've imported, there's just one line about importing Darwin.C.stdint.
Basically, there are a few purposes for modules; they improve compile times by cutting down on redundant compilation tasks, and they prevent people from messing with library headers via #defines like you're trying to do. ;-) For more on Objective-C modules, how they work, and the rationale behind them, see this link:
https://clang.llvm.org/docs/Modules.html#introduction
Of particular interest to your question are the following excerpts:
The primary user-level feature of modules is the import operation, which provides access to the API of software libraries. However, today’s programs make extensive use of #include, and it is unrealistic to assume that all of this code will change overnight. Instead, modules automatically translate #include directives into the corresponding module import. For example, the include directive
#include <stdio.h>
will be automatically mapped to an import of the module std.io. Even with specific import syntax in the language, this particular feature is important for both adoption and backward compatibility: automatic translation of #include to import allows an application to get the benefits of modules (for all modules-enabled libraries) without any changes to the application itself. Thus, users can easily use modules with one compiler while falling back to the preprocessor-inclusion mechanism with other compilers.
And later on:
If any submodule of a module is imported into any part of a program, the entire top-level module is considered to be part of the program. As a consequence of this, Clang may diagnose conflicts between an entity declared in an unimported submodule and an entity declared in the current translation unit, and Clang may inline or devirtualize based on knowledge from unimported submodules.
Or, if you'd prefer to turn them off and get more traditional C-like behavior, you can simply set Enable Modules (C and Objective-C) to No in Xcode's Build Settings, or compile without the -fmodules flag if you're using the command line.

How to handle 'Object': ambiguous symbol in Visual Studio

I am creating a C++/CLI wrapper for native C code that has it's own Object typedef and am receiving the C2872 'Object': ambiguous symbol error when linking. The compiler output is:
1>C:\src\OS_kernel.h(27): error C2872: 'Object': ambiguous symbol
1>C:\src\OS_types.h(261): note: could be 'ObjectStruct *Object'
1>C:\src\OS_kernel.h(27): note: or 'System::Object'
It may be worth mentioning that I am mocking this native C code for the purposes of the C++/CLI wrapper; not sure if that opens up a potential solution that would otherwise not be available if no source code was available. I'm guessing there is a way to specify which definition I want the code to use, but I don't know how to specify that. Is that possible? I want to specify it to use the ObjectStruct *Object.
It would be great if I didn't have to modify the mock code since it could potentially be hundreds or thousands of individual places.
As an aside, I am also receiving this error for other types the native library is using, such as Buffer and Boolean.
OK, since you're getting the error in OS_kernel.h, I'm guessing that's part of the C code you're wrapping.
Obviously, one possible solution is to treat the name Object as a reserved word, and edit your C code to not use it. One could argue that this is the most correct solution, but it may not be possible to do that.
Depending on how you're referencing the C code, it may be reasonable to compile it as C++, and stick it entirely within a namespace. That way, when the C code (now C++ code) uses Object it will see the typedef within its namespace, and you'll have the option to reference either namespace in your code.
The fact that you're getting this error from your library's header file indicates to me that you've got a using namespace System; directive, and that the #include of your library's header files comes after that using directive. Consider removing the using namespace System;, or at least moving it after the #include. This way, you won't get that error in the library's headers, you'll just have to deal with it in your code.

Can simply importing a header ever lead to run-time issues?

I realize that doing this can lead to compile errors. But is an import always safe if no (new) compile errors or warnings arise? If I use an import statement (e.g. to remove duplicate protocol definition warning), could doing so, on it's own, ever change the run-time behavior? What checks (if any) are necessary to ensure invariability of operation after a new header import?
Yes, importing a header can lead to run-time issues.
For example, you may get a warning that a selector is unknown so the compiler is making assumptions about its signature. If you fix that warning by importing the relevant header, then that changes the code the compiler is emitting. Generally, it would change the code from broken to correct, but that nevertheless results in a run-time change.
If you use #import, then the header could define preprocessor macros that radically alter the subsequent code. For example, it could #define setNeedsDisplay setHidden or something.
The only way I can think of to verify that importing the header didn't alter the generated code is to examine the generated code and compare before and after. You can ask Xcode or clang to produce assembly from the compilation. You could also use otool -tV to disassemble the binaries (although that wouldn't show changes in, say, static data like strings).

Static, extern and inline in Objective-C

What do static, extern and inline (and their combinations) mean in Objetive-C using the LLVM compiler?
Also, I noticed that there are CG_EXTERN and CG_INLINE macros. Should we be using those instead?
(I couldn't find a source with a clear explanation so I thought it might be useful to create one here, or point to it if someone knows one)
What do static, extern and inline (and their combinations) mean in Objetive-C using the LLVM compiler?
The same as in C, unless you compile as ObjC++ -- then they mean the same as found in C++.
So here is an introduction for C, but read the links if you are ready to use these because the details are important:
Extern
Summary: Indicates that an identifier is defined elsewhere.
Details: http://tigcc.ticalc.org/doc/keywords.html#extern
Static
Summary (value): Preserves variable value to survive after its scope ends.
Summary (function): Effectively emits unnamed copies - useful for private functions in C, and can be used to escape multiple definition errors when used with inline functions.
Details: http://tigcc.ticalc.org/doc/keywords.html#static
Inline
Summary: Suggests the body of a function should be moved into the callers.
Details: http://tigcc.ticalc.org/doc/gnuexts.html#SEC93
Note that inline and static are quite a bit more complex in C++ (like pretty much everything in C++).
I also found that there are CG_EXTERN and CG_INLINE macros. Should we be using those instead?
No.
Instead, you should specify your own, with your own meanings, if you need this type of functionality. CG_EXTERN and CG_INLINE have specific meanings (which may change), and are meant to be used in their defined context -- also, you don't want to have to include a whole handful of frameworks (all CoreGraphics/ApplicationServices/CoreFoundation/etc.) when you want to specify something is extern in a way that works in C and C++.
Justin covered most of it, but I found some other nice resources for those who want to dig deeper:
By declaring a function inline you tell the compiler to replace the complete code of that function directly into the place from where it was called. This is a rather advanced feature that requires understanding of lower-level programming.
Inline functions
This SO question has an enormous answer about extern variables - variables defined "somewhere else" - but need to be used also "here".
Static preserves variable life outside of scope. The Variable is visible within the scope it was declared.
What does a static variable mean?

Can the gcc static linker properly inline functions from a static library?

If we compile a number of source codes which makes uses of a static library named lib.a, would the inline functions in lib.a get properly inlined with the rest of binaries?
no, they would not. Inlining is an operation on the parse tree and requires access to the source code for both the host and donor sources of the inlined code.
Static libraries have already been compiled from source to binary at the point you use them, so inlining cannot happen.
However, code that is not inlined is also 'proper' and will function just fine (assuming it got compiled into the static library at all).
Well, since in order to even attempt to call an inline function its declaration must be visible at the call site. If it is then inline then the compiler will either inline it or completely ignore the request.
If you are wondering if functions NOT declared inline that were inlined in the library can then also be inlined when you link to the final product...this would depend on the implementation and, assuming it is already capable of LTO (since it did it to the library), it very well might be able to inline them again. You may be required to cause the implementation to include the definition even when it's been inlined everywhere though...all depends on the implementation.
http://crazyeddiecpp.blogspot.com/2010/12/inline-functions-and-you.html