unscoped enums in C code with VS2015 - c

I'm trying to compile the psutil module for Python, using VS 2015 and the Windows 10 SDK. Compilation fails with the following error:
c:\users\builder\documents\code\psutil\psutil\arch\windows\ntextapi.h(212): error C2365: 'ProcessBreakOnTermination': redefinition; previous definition was 'enumerator'
C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\um\winternl.h(308): note: see declaration of 'ProcessBreakOnTermination'
c:\users\builder\documents\code\psutil\psutil\arch\windows\ntextapi.h(212): error C2086: '_PROCESSINFOCLASS2 ProcessBreakOnTermination': redefinition
c:\users\builder\documents\code\psutil\psutil\arch\windows\ntextapi.h(212): note: see declaration of 'ProcessBreakOnTermination'
Further investigation shows ProcessBreakOnTermination is part of an enum (PROCESSINFOCLASS) in winternl.h.
I believe this has to do with C++11's enforcement of scoped enums: https://msdn.microsoft.com/en-us/library/vstudio/2dzy4k6e(v=vs.110).aspx
However, I am lost on how to address this issue. If I try to add the class or struct bits as detailed on that MS website, I get compiler errors, since this is being compiled as C code. Why should the C++11 rules apply to C code here?

The solution I came up with was to wrap the offending dual-defined symbols in a #if.
(start of enum)
(last good entry)
#if _MSC_VER < 1900
(offending enum entry)
#endif
(next entry) = (last_good_entry)+2
Any nicer solutions are welcome!

Related

Preprocessor: error: missing binary operator before token "("

we're curruntly working on a C project and we've downloaded and used the header dirent.h, the problem is the code was compiled successfully on my teammate laptop but in mine it doesn't compile, telling me this :
In file included from utils.c:6:0:
dirent.h: In function '_wopendir':
dirent.h:383:28: error: missing binary operator before token "("
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
^
dirent.h:405:28: error: missing binary operator before token "("
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
^
dirent.h:413:5: warning: implicit declaration of function 'wcsncpy_s' [-Wimplicit-function-declaration]
wcsncpy_s (dirp->patt, n+1, dirname, n);
^
I searched for the problem and find that it's a preproccessor error and currently on the #if
i've tried to add #define WINAPI_FAMILY_PARTITION(Partitions) but it doesn't work.
Please suggest me a solution to compile it successfully, and does the windows version affect on preprocessing?
WINAPI_FAMILY_PARTITION is defined in <winapifamily.h>, probably included by <windows.h>. Look at this question for more explanations, but windows intricacies are largely irrelevant for your compilation issue. You might want include <windows.h> before <dirent.h>?
You did not publish the source code for your program, nor did you specify what OS you compile for not what compiler you use, but you mention we've downloaded and used the header dirent.h... This sounds wrong: system include files such as <dirent.h> are automatically installed with the compiler, they are specific to the OS and compiler, you cannot just download one from the net and expect it to work on your system. It might work by chance on your teammate's PC because the OS might be different.

Hello World driver won't compile correctly

I started out driver development, however I followed some tutorials I met online here and I am trying to compile my driver into a simple .sys file.
The code looks like this:
#include <ntddk.h>
#include <wdf.h>
#define UNREFERENCED_PARAMETER(P) (P)
VOID DriverUnload(PDRIVER_OBJECT driver)
{
DbgPrint("first:HelloWorld End!");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pUnicodeString)
{
DbgPrint("first:HelloWorld Begin!");
pDriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
Rather than compile, I get this very funny error:
Error C2220 warning treated as error - no 'object' file generated MyHelloWorldDriver C:\Users\****\source\repos\MyHelloWorldDriver\MyHelloWorldDriver\main.c 7
I am lost as I dont know where else to seek answers from. I have checked and checked all and I get this funny error which happens to work fine on other versions of Visual studio. If I remove the warnings, I don't see it to have a worry, it compiles fine and does not send any errors to my screen, why is this so?
I am using Visual studio 2019, what could I apparently be missing ??
PS
The warnings I get look like this
Error (active) E1097 unknown attribute "no_init_all" MyHelloWorldDriver C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\km\ntddk.h 372
Error (active) E1097 unknown attribute "no_init_all" MyHelloWorldDriver C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\km\ntddk.h 1093
Warning MSB8038 Spectre mitigation is enabled but Spectre mitigated libraries are not found. Verify that the Visual Studio Workload includes the Spectre mitigated libraries. See https://aka.ms/Ofhn4c for more information. MyHelloWorldDriver C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppBuild.targets 422
Error C2220 warning treated as error - no 'object' file generated MyHelloWorldDriver C:\Users\***\source\repos\MyHelloWorldDriver\MyHelloWorldDriver\main.c 7
Warning C4566 character represented by universal-character-name '\uFF01' cannot be represented in the current code page (1252) MyHelloWorldDriver C:\Users\***\source\repos\MyHelloWorldDriver\MyHelloWorldDriver\main.c 7
Warning C4100 'driver': unreferenced formal parameter MyHelloWorldDriver C:\Users\***\source\repos\MyHelloWorldDriver\MyHelloWorldDriver\main.c 5
Warning C4566 character represented by universal-character-name '\uFF01' cannot be represented in the current code page (1252) MyHelloWorldDriver C:\Users\***\source\repos\MyHelloWorldDriver\MyHelloWorldDriver\main.c 12
Warning C4100 'pUnicodeString': unreferenced formal parameter MyHelloWorldDriver C:\Users\***\source\repos\MyHelloWorldDriver\MyHelloWorldDriver\main.c 10
Looks like an issue with Visual Studio:
https://developercommunity.visualstudio.com/content/problem/549389/intellisense-error-e1097-because-intellisense-does.html
Here is a copy from that link:
With Visual C++ 2017 version 15.8 (compiler version 19.15.26726.0) a new undocumented Compiler option /d1initall and
a new attribute __declspec(no_init_all) got added to the Compiler. Intellisense (VS17 and 19) does not recognize this attribute and says its unknown.
The Problem is Intellisense not knowing about the existence of the no_init_all attribute.
This attribute is used in the official Windows SDK and WDK 10.0.18362.0 header files,
that means Intellisense displays this error for all projects that include
Windows Kits\10\Include\10.0.18362.0\um\winnt.h (Line 588 & 1093) or
Windows Kits\10\Include\10.0.18362.0\km\ntddk.h (Line 7597).
You can also reproduce the Error by simply defining a struct with __declspec(no_init_all) Attribute,
__declspec(no_init_all) struct A {};
This Compiles fine without any warnings/errors but Intellisense says its wrong.
It has been fixed on 29th of April, 2019.
A possible fix is to add this code to one of the main header files:
#if (_MSC_VER >= 1915)
#define no_init_all deprecated
#endif
you can activate precompiled header in Tools/option/Text-Editor/C C++/Extension and set Disable Automatic Precompiled Header to false.

Matlab code to C using Matlab coder

I have some working Matlab code, which I try to transform into C code using the Matlab coder. I am getting this error:
18 c:\users\bla\project\strcmpi.h(79) : warning C4028: formal parameter 2 different from declaration
19 c:\users\bla\project\strcmpi.h(79) : error C2371: 'strcmpi' : redefinition; different basic types
20 c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\string.h(245) : see declaration of 'strcmpi'
21 NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\amd64\cl.EXE"' : return code '0x2'
22 Stop.
23 The make command returned an error of 2
24 'An_error_occurred_during_the_call_to_make' is not recognized as an internal or external command,
25 operable program or batch file.
It looks very C specific to me (I am not a proficient C programmer). Can anyone please point me in the right direction to overcome this error? Thanks.
PS:
Here is some adapted Matlab code:
if(strcmpi(parameters.x,'bladibla') == 1)
% some code
else
% some more code
end
where 'parameters' is a struct. I would like to stick to my struct but if there are better ways to achieve the above, especially in the context of the Matlab coder and C, please let me know.
The thing about strcmpi() (case-insensitive string comparison) is that it's not a standard C function. Thus, code that relies on it but tries to be portable across platforms sometimes has to provide its own implementation while deferring to the system's implementation if available. In my experience, the project's own strcmpi() implementation will be protected by a configuration option. If you open up c:\users\bla\project\strcmpi.h, you might see code similar to this:
#ifndef CONFIG_STRCMPI_PRESENT
int strcmpi(const char *string1, const char *string2);
#endif // CONFIG_STRCMPI_PRESENT
If you see this, the trick to getting around the problem will probably be to find the associated config.h file and uncomment the following line:
// #define CONFIG_STRCMPI_PRESENT
This is all just a guess based on my experience with similar issues.

Compilation error in visual C++

I am using Visual studio 2010 for building C project. My project contains a number of header files,source file and parsers. It uses lex and bason files. I am getting a single error during the compilation and íé the following
abc.y:error C2065: 'INPUT' : undeclared identifier
I tried the solutions I am getting like including
#define WIN32_WINNT >= 0x0501
in my main.c file before the inclusion of any of the header files.I am not able to get rid of this error. Could you please let me know what Can be the reasons for this error?
EDIT
The snippet of code that is showing error is:
list_Cons(0, list_List((POINTER)INPUT)
The surprising thing is that If i alter INPUT into INPUT1, I get the same error. It is stoic to change.
Presumably you read this and this.
#define WIN32_WINNT >= 0x0501 wont work. You should try using #define WIN32_WINNT 0x0501 instead.
Also, check that you are actually #including winuser.h
A C++ compiler cannot process a *.y file. For that you need a yacc / bison program, which does not come included with Visual Studio 2010.
For myself I use CMake which can generate MSVC projects along with other build types. You can tell it that a .y needs to be processed outwith the C/C++ files and it will instruct MSVC to invoke whatever external tools are necessary to preprocess the non-C/C++ parts.

Why does Eclipse CDT say: 'syntax error', but compilation no problem

I am working in existing C code which has a couple of lines with statements similar to this one:
struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(struct collect_conn, runicast_conn));
The struct collect_conn goes along the following lines:
struct collect_conn {
struct runicast_conn runicast_conn;
struct announcement announcement;
const struct collect_callbacks *cb;
struct ctimer t;
uint16_t rtmetric;
uint8_t forwarding;
uint8_t seqno;
};
I am using Eclipse CDT, and it marks the line with an orange squiggly line as 'syntax error'. I think it is marked as such by the CDT indexer.
However, compilation (manually in a terminal) is no problem.
This is a bit inconvenient however, since the elements on the line don't get indexed (so the call hierarchy tree isn't always correct, or the highlighting of elements, etc.)
Why does Ecipse not like the line as it is?
Eclipse CDT contains its own preprocessor/parser for analyzing your code and building an index. However, when you invoke a build CDT calls out to your system compiler, like gcc for example. There may be minor differences between the syntax accepted by the CDT parser and the syntax accepted by your compiler. When this happens the CDT parser can get confused.
On my system the offsetof macro expands into an expression that uses the __offsetof__ keyword. This keyword isn't recognized by CDT so that's why there's a syntax error. To deal with this problem the CDT parser has a macro built in to deal with __offsetof__ which looks like this:
#define __offsetof__(x) (x)
This doesn't appear to be correct, at least on my system the result is the removal of the __offsetof__ keyword from the source which still leads to a syntax error.
I was able to get rid of the syntax error by going to the Paths and Symbols property page and adding a macro for __offsetof__ which maps to 'foo'. This tricks the parser into thinking its just a call to a function it hasn't seen before, but not a syntax error.
Alternatively you can turn off syntax error reporting in the editor by going to Window > Preferences > General > Editors > Text Editors > Annotations and unchecking all the checkboxes for C/C++ Indexer Markers.
I've fixed problem in eclipse CDT with Preferences->C/C++->Language Mappings : Add
Content Type : C-header
Language : C++
Sometimes, although the code compiles with no error, eclipse CDT's real-time code analyzer shows some errors in C/C++ files (eg. 'Function xxx could not be resolved). This is because eclipse CDT uses its own preprocessor/parser for analyzing the code and building the indexes instead of the MinGW's one (or any other GNU compiler). In order to fix this globally for all eclipse projects in the workspace, follow these steps:
(In order to fix this only for a specific project, follow steps 1, 2 and 4 in menu 'Project->Preferences')
1-In menu 'Window->Preferences->C/C++->Language Mappings', add the correct mappings as shown in below: (eg. for content types: C++ Source/Header File, use GNU C++ language and so on)
2-In menu 'Window->Preferences->C/C++->Indexer', set full indexing by checking all checkboxes (but not 'Skip' ones) as shown in below:
3-In each project's specific properties, menu 'Project->Properties->C/C++ general->Indexer', Uncheck 'Enable project specific settings' as shown in below:
4-Rebuild the indexing, menu 'Project->C/C++ Index->Rebuild'.
It seems the CDT parser doesn't like the portion offsetof(struct ...).
If you declare collect_conn using a typedef the error goes away. At least for me, the following code works:
typedef struct {
struct runicast_conn runicast_conn;
struct announcement announcement;
const struct collect_callbacks *cb;
struct ctimer t;
uint16_t rtmetric;
uint8_t forwarding;
uint8_t seqno;
} collect_conn;
...
struct collect_conn *tc = (struct collect_conn *)
((char *)c - offsetof(collect_conn, runicast_conn));
If you can't change the original declaration do something like this:
typedef struct collect_conn collect_conn_t;
It might be confused, check if you have a definition of offsetof in-scope, for instance. Otherwise you might try simplifying the expression, breaking it up using e.g. a #define with the offset of, or something.
I'm thinking the compiler might provide a built-in version of offsetof, while Eclipses's compiler/code-parser might not. If so, you would need to make sure you have the definition, for Eclipse to be able to properly parse your code.
try switching the indexer to "Full c/C++ indexer (complete parse)" in Preferences->c/C++ -> indexer
Iv got the same problem. There is 2 definition of offsetof (one for C and one for C++). IMO the problem come from that
For example if i type
#ifndef __cplusplus
#endif
Eclipse will grey it. It mean __cplusplus is defined, but my project is a C
Unfortunatly i dont find a fix.
I fixed similar problem after checking the tab Error Parsers in Makefile Project in New CDT Project Wizard, removing CDT Visual C Error Parser (I am using gcc)
I ended up solving the problem like this. First I opened the project properties, then the C/C++ general->Paths and Symbols category. Under the Symbols tab I added this entry:
Symbol: offsetof(TYPE,MEMBER)
Value: ((ssize_t) &((TYPE *)0)->MEMBER)
These symbols are used by the indexer but not passed to the compiler (at least in Makefile projects, I haven't tried it in the other kind of C project), so it doesn't override GCC's built-in offsetof
I've seen Eclipse do this some times, and I use it for Java. Usually closing and opening the file again fixes it for me (resets whatever is wrong). It usually seems to be an error that WAS there but has been fixed and the "error cache" isn't updated correctly.

Resources