suppress gcc warnings : "warning: this is the location of the previous definition" - linux

I need a set of wrappers around the standard system calls-open,listen,etc.
For these i have a few "#define" as in:
#define open(a,b,c) JCL_Open(a,b,c)
But when i compile the header and associated .c files, i am getting the following warning:
/jcl_wrappers.h:114:1: warning: "open" redefined
/jcl_wrappers.h:113:1: warning: this is the location of the previous definition
How can i suppress these warnings?

Put include guards in your header file.
Basically you need to put these two lines at the beginning of your header file
#ifndef _yourincludefilename_h_
#define _yourincludefilename_h_
and
#endif /* _yourincludefilename_h_ */
at the end of you include file.
Edit:
rascher is right, that open is not a good name for a macro, as it will conflict with a library function. Usually it is good C convention to make macros all uppercase, so I would suggest to change your macro to
#define OPEN(a,b,c) JCL_Open(a,b,c)
or even better
#define XYZ_OPEN(a,b,c) JCL_Open(a,b,c)
where XYZ is a prefix specific to your code.

Leave the standard functions alone and rename the function:
#define myopen(a,b,c) JCL_Open(a,b,c)
Someone will thank you later.

You might try using compile guards. Like:
my_headers.h:
#ifndef __MY_HEADERS
#define __MY_HEADERS
#define open(a,b,c) JCL_Open(a,b,c)
#endif
This will only do do what is between the #ifndef and #endif if the '__MY_HEADERS' macro has been defined. So, everything in your .h file will only be declared once.
You could use the same construct to see if the "open" macro is already defined.
Also be aware that there is already a C function called open(): http://www.manpagez.com/man/2/open/ . May not be a great idea to use the same name for your macro!

Wrap the define in:
#ifndef JCL_WRAPPERS_H
#define JCL_WRAPPERS_H
... your macro's
#endif
This makes sure your macro's are only defined once if you including your header in multiple places.
It's generally a smart thing to do for all prototypes in headers also.

Related

Include once capability in Inno Setup Preprocessor?

I am creating a library of script methods and only want to include them when needed in my installers.
Some of the methods need to use other methods so I was putting the #include "filename.iss" for the needed methods in the file with the method that needs it.
However, if I include two files in an installer script file that also include a common file I get a "Duplicate identifier" error in the second file that includes it.
I've searched for something like #include-once but can't find any results for it.
To reproduce you can just include the same file twice:
#include "AddReplaceLinesInFile.iss"
#include "AddReplaceLinesInFile.iss"
The only way I can see to avoid this is to not put the includes in the files with the methods that need them and just add them in the main installer script.
I'm leaving the includes in the top of the method files that need them but commenting them out - for documentation purposes and to make it easy to copy and paste them into my main installer script. However I'd prefer to use something like an include-once capability.
Does Inno Setup have anything like include-once or a way to test for an already defined method so I could create something similar?
TIA
Use the same trick as is used in C/C++, the include guard:
In the C and C++ programming languages, an #include guard, sometimes called a macro guard, is a particular construct used to avoid the problem of double inclusion when dealing with the include directive.
Surround the code in the included file with #ifndef UniqueName, #define UniqueName ... #endif:
#ifndef IncludeIss
#define IncludeIss
procedure Test;
begin
end;
#endif
The UniqueName is typically the same as filename, with punctuation removed (to make it a valid identifier). I.e. for include.iss the name can be IncludeIss.
See Inno Setup Preprocessor: #ifdef, #ifndef, #ifexist, #ifnexist.
There is no such thing as include-once.
Inno Setup is Pascal based where functions (and procedures) are global! There are no private ones.
Preprocessor Symbols are scoped to the .iss file and to make them global use public keyword.
Variables have really unpleasant behavior: if you define global variable (in [Code] section) with the same name as local variable you never know into which variable the value is really assigned.
Compiler does not check this which is really bad.

Preprocessor definitions in code and project properties

I have simple console application in which I must set preprocessor definition _CRT_SECURE_NO_WARNINGS. According to my understanding I can set it my code right after #include "stdafx.h" by puting line #define _CRT_SECURE_NO_WARNINGS or in Project Properties -> Preprocessor -> Preprocessor Definitions. If I do first way I still have problems in code if I do second way - it solves my problem. Why I can't define #define _CRT_SECURE_NO_WARNINGS in source code?
The best way to solve this problem is really on the project properties, causing it to be used globally as a compiler flag. If you use the #define _CRT_SECURE_NO_WARNINGS in a file, only that file will have that warning suppressed.

winsock deprecated no warnings

I am trying to create a UDP multicast socket program using VS2015 (C++ console application).
I got the following error,
Error C4996 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings mulitcast_listener
I tried to add _WINSOCK_DEPRECATED_NO_WARNINGS symbol to my project settings via "Project"->"Properties"->"Configuration properties"->"C/C++"->"Preprocessor"->"Preprocessor definitions"
.. But still it says the same.
And then I tried to add symbol above #include "stdafx.h"
like
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
and then No(/sdl-) on "Project"->"Properties"->"Configuration properties"->"C/C++"->General->SDL checks
now I get a error message saying
Warning C4603 '_WINSOCK_DEPRECATED_NO_WARNINGS': macro is not defined or definition is different after precompiled header
Finally I tried to implement
inet_pton(AF_INET, HELLO_GROUP, (PVOID *)(&mreq.imr_multiaddr.s_addr));
instead of
mreq.imr_multiaddr.s_addr = inet_addr(HELLO_GROUP);
I need to understand why the error didn't resolved even after adding the _WINSOCK... macro.
Thanks in advance.
As noted in the comments, the solution is to make sure that the line
#define _WINSOCK_DEPRECATED_NO_WARNINGS
is placed after
#include "stdafx.h"
but before the other #include statements.
While the previous advice works, it is ignoring the purpose of stdafx.h. The idea is that you place #include statements for header files that don't change frequently inside stdafx.h in order to make use of precompiled headers. Therefore you should ideally place
#define _WINSOCK_DEPCRECATED
inside stdafx.h, before other #include statements that it affects, in particular before including winsock2.h or other winsock related headers.
// pch.h
#ifndef PCH_H
#define PCH_H
#define _WINSOCK_DEPRECATED_NO_WARNINGS // defined here and it worked
#include "framework.h"
#include "xxx.h"

ensure config.h is included once

I have a library project that I'm working on porting to using the autotools suite in Linux. I'm quite new to autotools (this week). I've learned the basics of its operation. I have a question about how to keep the contents of config.h from being redefined.
I'm surprised to find that the generated config.h file doesn't either, 1) wrap each macro in a #ifndef or, 2) that the entire file isn't wrapped in the standard #ifndef CONFIG_H.
As I've alluded, this code is built on Windows and Linux. Thus there are several uses of a macro, _linux (I'm not saying that's the best name, but it's in use everywhere) to bring in elements to classes which exist in Linux only. Thus, this will happen
header.h
#ifndef HEADER1_H
#define HEADER1_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif
source.cxx
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "header.h" // oops, preprocessor gets excited because of redefs
One simple solution is I do that standard unique wrap in config.h.in after the file is generated. However, I was wondering, is there a better way of handling this? I can't be the first to encounter this and there might even be a means of handling it in configure.ac but being a complete neophyte in this, I don't know what to even search for.
The way I do this is indeed creating a wrapper file (which I usually call global.h) that reads like this.
#ifndef MY_PROJECT_GLOBAL_H
#define MY_PROJECT_GLOBAL_H
#include <config.h>
/* Maybe other global definitions… */
#endif
Note that the recommended way to #include the config.h file is via <config.h> not "config.h" so it works better with VPATH builds.
Then, all the source files in my project #include this global.h header as their very first #include and don't care about config.h. A header file should never #include config.h since this would lead to bad name conflicts. Actually, if you stick to this guideline, your code should also work without #include guards in the configuration header.
Update regarding OP's comment
Or: How to use configuration results in headers?
If your headers need to declare different things depending on the results of the configure script, you have a number of options, none of which is perfect.
For internal headers, there is no problem. They simply rely on the macros being #defined without #includeing anything. This works if – as is recommended – all source files #include (maybe indirectly as shown above) config.h before any other header.
If the headers are to be installed publicly, this is not such a great solution. For those of your users that use Autoconf, it wouldn't be that bad, although even those would have to remember what checks to place in their configure.ac files. For users who don't use Autoconf, it will be pretty bad. If you only have a few switches (such as Glibc's fature test macros), it is okay to ask your users to #define them before #includeing your headers but if you need many, this is not a real option. Not to mention that you'll expose a lot of implementation details to your users that way.
If all you need to do is branch depending on the platform you are building for, you could probe some of the pre-defined macros like __linux or _WIN32. There is the Boost.Predef library that aims to make these check a little more convenient by providing a higher-level abstraction. The library works with C and C++ alike but, of course, it adds an additional dependency to your project.
Finally, you could make a version of your config.h that uses a macro prefix specific to your project. There is a contribution in the Autoconf macro archive that does exactly that for you. A minimal example could look like this.
AC_PREREQ([2.69])
AC_INIT([example-project], [1.0], [bugs#example.org])
AC_CONFIG_SRCDIR([example.c])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AX_PREFIX_CONFIG_H([public_config.h], [EXAMPLE_PROJECT], [config.h])
AC_PROG_CC
AC_OUTPUT
Save this as configure.ac, download ax_prefix_config_h.m4 from the Autoconf macro archive and place it in the sub-directory m4 and then run autoreconf && ./configure. It will create the normal config.h and in addition public_config.h where in the latter file, all macros are prefixed with EXAMPLE_PROJECT_. The file public_config.h (which also has #include guards by the way) can be installed and #included in your project's public header files if need be.
With autoheader, you can add header and trailer boiler plate code to config.h
https://www.gnu.org/software/autoconf/manual/autoconf-2.60/html_node/Autoheader-Macros.html
For example, add the following to your configure.ac
#
# Add include guards to config.h
#
AH_TOP([
#ifndef __CONFIG_H_INCLUDE_GUARD
#define __CONFIG_H_INCLUDE_GUARD
])
AH_BOTTOM([
#endif
])

inconsistent dll linkage & definition of dllimport static data member not allowed

Assuming I have these two files:
Header.h
class DLL ExportClass{
public:
ExportClass();
static int test;
};
Source.cpp
#ifdef EXPORT
#define DLL __declspec(dllexport)
#else
#define DLL __declspec(dllimport)
#endif
#include "Header.h"
int ExportClass::test = 0;
ExportClass::ExportClass(){
}
And I won't define EXPORT (to import a already exported class with a static member), why do I get these warnings:
1>source.cpp(11): warning C4273: 'test' : inconsistent dll linkage
1> header.h(4) : see previous definition of 'public: static int ExportClass::test'
1>source.cpp(13): warning C4273: 'ExportClass::ExportClass' : inconsistent dll linkage
1> header.h(3) : see previous definition of '{ctor}'
And this error:
1>source.cpp(11): error C2491: 'ExportClass::test' : definition of dllimport static data member not allowed
If I define EXPORT it works. I kind of understand the warnings, but I thought, that the static variable and the ctor could be ignored by the compiler, because the whole class is declared as __declspec(dllimport) anyway. I want to use the same codebase for the __declspec(dllexport) and __declspec(dllimport) - but it seems the compiler stll tries to define these symbols that are marked as __declspec(dllexport) in their declaration. What is the common practice to solve this problem?
You are expecting the compiler to ignore a very serious mishap. It encountered the __declspec(dllimport) attribute on the class declaration, that quite unequivocally states that the class implementation is present in different module that's going to bound at runtime. But then it encountered the definition as well, completely unexpected since the attribute contract says that it is compiled in an entirely different project.
The C4273 warning is generated to remind you that it is very unclear what function is actually going to execute at runtime. There are two, one that is busy compiling, another in the DLL. Which one will actually execute is a wild guess. C4273 is a level 1 warning, the kind that fit the "this is almost surely wrong" category. It is not entirely impossible to work okay since there's some expectation that the functions have at least the same code. The odds that will not cause trouble are however not great, it could only work if the function doesn't have any side effects that change the internal DLL state. Very hard to diagnose bug when it does btw.
Then it encountered the exported variable. Same case, there are two of them. This is where the compiler programmer put his foot down, having code randomly use one or the other is no longer something that can be ignored. That just cannot ever work, the variables cannot have the same value. So C2491 is a hard error.
No idea how you got in this pickle, clearly the road you're trying to travel will make you fall off a steep cliff.
The only way I can reproduce your problem is to do the following:
Create a Win32 DLL project, call it Project1
Add the source code as you described
Compile the DLL and LIB
Change the project properties to remove EXPORT from the preprocessor definitions
Attempt to compile again (then I see your errors/warnings)
If, instead of steps 4 and 5, I do the following, I do not see an error:
Create a Win32 console application, call it Project2
Add source code as follows:
#include "Project1.h"
#pragma comment(lib, "Project1.lib")
int _tmain(int argc, _TCHAR* argv[])
{
ExportClass pClass;
return 0;
}
I suspect you see those errors because you are doing everything from the same DLL project and it is overwriting the LIB that it previously created and then attempting to import it.
If I am correct in guessing what you did, can you try using your DLL/LIB from another project and see what happens?
Although it is an old thread, it will be probably read by others. Therefore, if you want to make this code cross-compilable, I would usually define a header "export.h" like:
export.h
#pragram once
#if ! defined(DLL_API)
# if defined(_WIN32) // for windows builds
# if defined(myDLL_EXPORTS)
# define DLL_API __declspec(dllexport)
# else
# define DLL_API __declspec(dllimport)
# endif
# else // for linux builds
# define DLL_API
# endif
#endif
and include it in all the classes (.h) you want to export from your dll. You will also have to define the variable myDLL_EXPORTS as a parameter of the compiler for the dll project.
The way it works is very simple, when you are compiling your dynamic library (dll/so), because the variable myDLL_EXPORTS is defined, the compiler will replace DLL_API with __declspec(dllexport) so that your class can be consumed by the user of your dll. Conversely, when you are including the header file where you want to use your class at, because the variable myDLL_EXPORTS is not defined in the consumer project (it is defined only in the DLL project), the compiler will replace myDLL_EXPORT with __declspec(dllimport), so it knows that your class symbols are defined somewhere else (in this case, defined in your dll/so).
Finally, as __declspec(...) is a Windows-only thing, for linux we replace DLL_API with nothing.

Resources