Problem with using enumeration states in multiple header files [duplicate] - c++

This question already has answers here:
How to declare a global variable in C++
(5 answers)
Variable already defined in .obj; What is going on here?
(6 answers)
Closed 3 years ago.
I wanted to have an enum class with it's object declared in the header file of my program. I need to modify the state multiple times during the program but it doesn't allow me to. When I run the program it says that there was a multiple definition error regarding the enum class.
I changed the object into static and the program worked (static combinations state;), but in an attempt to assign the state to something else it didn't change the state. In another cpp file I tried modifying the state this way (state = combinations::HIGHCARD)
#ifndef POKER_H_
#define POKER_H_
enum class combinations {
HIGHCARD, ONEPAIR, TWOPAIRS, THREEOFAKIND, STRAIGHT,
FLUSH, FULLHOUSE, FOUROFAKIND, STRAIGHTFLUSH, ROYALEFLUSH
};
combinations state;
void shuffle(int[][13]);
void assign(const char *[], const char *[], int[][13], const char *[], const char *[]);
int deal(const char *[], const char *[], const char *[]);
void printHand(const char *[], const char *[]);
void printWinningMassege(const int, const int, combinations, combinations);
bool isRoyalFlush(const char *[], const char *[], const char *[]);
int isStraightFlush(const char *[], const char *[], const char *[]);
int isFourOfaKind(const char *[], const char *[]);
int isFullHouse(const char *[], const char *[]);
int isFlush(const char *[], const char *[], const char *[]);
int isStraight(const char *[], const char *[]);
int isThreeOfaKind(const char *[], const char *[]);
int isTwoPair(const char *[], const char *[]);
int isPair(const char *[], const char *[]);
int isHighCard(const char *[], const char *[], const char *[]);
#endif // !POKER_H
Severity Code Description Project File Line Suppression State
Error LNK2005 "enum combinations state" (?state##3W4combinations##A) already defined in Poker.obj PokerDeals C:\Users\BoB\source\repos\PokerDeals\main.obj 1

Related

How to create multiple typedefs of similar format?

I'm dynamically loading a DLL that has quite a few methods and I have a typedef that handles several of the DLL methods:
typedef int32_t (__cdecl *MYPROC)(const char *url, const char *options, const char *body, int32_t length); // GET, POST, HTTP test
Whenever I create another typedef to handle a separate function:
typedef int32_t (__cdecl *MYPROC)(const char *json_blob, const char *response, int32_t length); // ParseVal
I am met with errors about conflicting declarations:
conflicting declaration 'typedef int32_t (__attribute__((cdecl)) * MYPROC)(const char*, const char*, int32_t)'
typedef int32_t (__cdecl *MYPROC)(const char *json_blob, const char *response, int32_t length); // ParseVal
^
note: previous declaration as 'typedef int32_t (__attribute__((cdecl)) * MYPROC)(const char*, const char*, const char*, int32_t)'
typedef int32_t (__cdecl *MYPROC)(const char *url, const char *options, const char *body, int32_t length); // GET, POST, HTTP test
I'm unsure if this is the correct approach to handle the DLL methods so I am open to suggestions. I am new to this feature of C++ and haven't used the language in quite some time so apologies if this is obvious.
Answered by StoryTeller - Unslander Monica. I was thinking MYPROC was WinAPI defined and not a name for some reason.

cppcheck format string on member functions of C++

aa.h
#ifndef __US_LOG_FILEA_H_
#define __US_LOG_FILEA_H_
namespace AA{
class A{
public:
A();
~A();
static A& Ins(){
static A obj;
return obj;
}
void do_p(const char *cat, int level, const char *Format ...); // ok
void do_p(const char *cat, int level, const char *Format, ...); // error
};
} // namespace AA
extern AA::A g_A;
#endif // __US_LOG_FILEA_H_
formatstr.cpp
void test()
{
g_A.do_p("global func", 2, "%s\n", str);
}
a.cfg:
<?xml version="1.0"?>
<def>
<function name="AA::A::do_p">
<noreturn>false</noreturn>
<leak-ignore/>
<formatstr type="printf"/>
<arg nr="3">
<formatstr/>
<not-uninit/>
</arg>
</function>
</def>
cppcheck --enbale-style --library=a.cfg formatstr.cpp
if void do_p(const char *cat, int level, const char *Format ...); cppcheck output:
warning: %s in format string (no. 1) requires 'char *' bu
t the argument type is 'std::string'. [invalidPrintfArgType_s]
g_A.do_p("global func", 2, "%s\n", str);
but do_p(const char *cat, int level, const char *Format,...); cppcheck output nothing
WHY?
The Cppcheck's version is 1.89.0.0
Thanks in advance.
WHY?
void do_p(const char *cat, int level, const char *Format ...); // ok
Presumably because cppcheck doesn't recognise const char *Format ... as a printf format and variadic arguments unless they are separated by comma, so you didn't get the error.
void do_p(const char *cat, int level, const char *Format, ...); // error
You configured cppcheck to check bad format / argument pairing, so this is where you should expect an error.
1st, modify the Cpp member function code to C-style function
2nd, remove overload funcions

undefined reference to c++ static library from c code when compiling using g++

I want to try interfacing C++ from C using the following setup:
interface.h:
#ifndef MY_TEST_INTERFACE_H
#define MY_TEST_INTERFACE_H
void *CreateDictionary();
void DictionaryAdd(void *self, const char *key, const char *value);
const char *DictionaryGetItem(void *self, const char *key);
void ReleaseDictionary(void **self);
#endif /* MY_TEST_INTERFACE_H */
lib.cpp
#include <unordered_map>
extern "C" void *CreateDictionary()
{
std::unordered_map<const char *, const char *> *dict = new std::unordered_map<const char *, const char *>;
return reinterpret_cast<void *>(dict);
}
extern "C" void DictionaryAdd(void *self, const char *key, const char *value)
{
std::unordered_map<const char *, const char *> *dict = reinterpret_cast<std::unordered_map<const char *, const char *> *>(self);
(*dict)[key] = value;
}
extern "C" const char *DictionaryGetItem(void *self, const char *key)
{
std::unordered_map<const char *, const char *> *dict = reinterpret_cast<std::unordered_map<const char *, const char *> *>(self);
return (*dict)[key];
}
extern "C" void ReleaseDictionary(void **self)
{
std::unordered_map<const char *, const char *> **dict = reinterpret_cast<std::unordered_map<const char *, const char *> **>(self);
delete (*dict);
*self = 0;
}
main.c
#include "interface.h"
#include <stdio.h>
int main(int argc, char **argv)
{
void *dict = CreateDictionary();
DictionaryAdd(dict, "color", "Green");
const char *str = DictionaryGetItem(dict, (const char *)"color");
puts(str);
ReleaseDictionary(&dict);
return 0;
}
What I did
I compiled lib.cpp using
g++ lib.cpp -o lib.obj -std=c++11 -std=gnu++11-c
Then built the static libary using
ar crf lib.a lib.obj
I am now trying to link lib.a with main.c using
g++ main.c lib.a -o main -std=c++11 -std=gnu++11
However I am getting the error:
C:\Users\Dmitry\AppData\Local\Temp\ccWnD011.o:main.c:(.text+0xf): undefined reference to `CreateDictionary()'
C:\Users\Dmitry\AppData\Local\Temp\ccWnD011.o:main.c:(.text+0x2f): undefined reference to `DictionaryAdd(void*, char const*, char const*)'
C:\Users\Dmitry\AppData\Local\Temp\ccWnD011.o:main.c:(.text+0x43): undefined reference to `DictionaryGetItem(void*, char const*)'
C:\Users\Dmitry\AppData\Local\Temp\ccWnD011.o:main.c:(.text+0x5f): undefined reference to `ReleaseDictionary(void**)'
collect2.exe: error: ld returned 1 exit status
I am building this on MINGW g++ 5.3.0.
I am curious why my C program can't find the references to the functions I marked under extern C, and compiled using g++ to ensure the c++ runtime is linked.

Apache module command parser prototype

I am creating an Apache2 module and experiencing a weird compilation problem.
This is prototype of my function used to parse config command named "analytics_ip":
static const char *apr_cfg_set_analytics_ip(cmd_parms *cmd, void *config, const char *data);
This is array of command_rec structures containing pointers to this function:
static const command_rec apr_cmds[] =
{
AP_INIT_TAKE1("analytics_ip", apr_cfg_set_analytics_ip, NULL, OR_ALL, ""),
{ NULL }
};
Structure command_rec is declared in header file http_config.h
typedef struct command_struct command_rec;
struct command_struct {
/** Name of this command */
const char *name;
/** The function to be called when this directive is parsed */
cmd_func func;
/** Extra data, for functions which implement multiple commands... */
void *cmd_data;
/** What overrides need to be allowed to enable this command. */
int req_override;
/** What the command expects as arguments */
enum cmd_how args_how;
/** 'usage' message, in case of syntax errors */
const char *errmsg;
};
When I follow cmd_func, it gets to the following declaration:
typedef const char *(*cmd_func) ();
If I am not mistaken, this means "pointer to function returning pointer to char and not accepting any arguments". How can this be possible? Command parsing function has to accept at least one parameter containing a module value of config variable corresponding to that function.
I am using g++ to compile this module.
Error message:
mod_xxx.h:65:2: error: invalid conversion from ‘const char* (*)(cmd_parms*, void*, const char*) {aka const char* (*)(cmd_parms_struct*, void*, const char*)}’ to ‘cmd_func {aka const char* (*)()}’ [-fpermissive]
};
Thanks in advance
cmd_func is a union, it is defined in http_config.h as follows:
typedef union {
/** function to call for a no-args */
const char *(*no_args) (cmd_parms *parms, void *mconfig);
/** function to call for a raw-args */
const char *(*raw_args) (cmd_parms *parms, void *mconfig,
const char *args);
/** function to call for a argv/argc */
const char *(*take_argv) (cmd_parms *parms, void *mconfig,
int argc, char *const argv[]);
/** function to call for a take1 */
const char *(*take1) (cmd_parms *parms, void *mconfig, const char *w);
/** function to call for a take2 */
const char *(*take2) (cmd_parms *parms, void *mconfig, const char *w,
const char *w2);
/** function to call for a take3 */
const char *(*take3) (cmd_parms *parms, void *mconfig, const char *w,
const char *w2, const char *w3);
/** function to call for a flag */
const char *(*flag) (cmd_parms *parms, void *mconfig, int on);
} cmd_func;
enum cmd_how args_how; is responsible for choosing the correct version of the function.
The switch handling it is located in server/config.c (in the invoke_cmd function).
You seem to be using the "take1" version which corresponds to cmd->AP_TAKE1 or simply cmd->take1.
The problem might be that C and C++ have differences regarding the union initialization. (AP_INIT_TAKE1 uses the { .take1=func } syntax which doesn't work in C++).
You'll have to initialize static const command_rec apr_cmds in a C++-compatible way or move it to a separate object file compiled with C. Or if you're not using C++ then simply compile with gcc.
For the project I'm working on we ended up adding a cast to allow the compilation to complete successfully, and the code seems to work OK as it correctly reads in the values specified in the configuration file. Here's the extract of this practice:
extern "C" {
static const command_rec kiwix_settings[] =
{
AP_INIT_TAKE1("zimFile", (const char* (*)())kiwix_set_zimfilename, NULL, RSRC_CONF, "The ZIM filename in full including the extension"),
AP_INIT_TAKE1("zimPath", (const char* (*)())kiwix_set_path, NULL, RSRC_CONF, "The path to the ZIM file, including the trailing //"),
{ NULL }
};
}
The full file (and indeed the project) are opensourced. Here's the link to the full file https://github.com/kiwix/kiwix-apache/blob/master/mod_kiwix.cpp
PS: thanks for your question and https://stackoverflow.com/users/257568/artemgr's answer as they helped me and another volunteer to work out how to resolve the problem for our project.

C++ errors, maybe coming from .h files, not sure

Ok, I am trying to compile a program:
g++ -std=c++0x a1test.cpp GS1Prefix.cpp EAN.cpp
But I am getting errors that I never seen before.
In file included from a1test.cpp:17:0:
EAN.h:3:25: error: âPrefixâ does not name a type
EAN.h:3:33: error: ISO C++ forbids declaration of âpâ with no type [-fpermissive]
a1test.cpp: In function âbool RegisteredTests(const Prefix*, int&, int*, int*)â:
a1test.cpp:222:68: error: no matching function for call to âisRegistered(const Prefix*&, const char [14], char [6], char [8], char [7])â
a1test.cpp:222:68: note: candidates are:
EAN.h:3:6: note: bool isRegistered(const int*, const char*, char*, char*, char*)
EAN.h:3:6: note: no known conversion for argument 1 from âconst Prefix*â to âconst int*â
GS1Prefix.h:10:6: note: bool isRegistered(const Prefix*, int)
GS1Prefix.h:10:6: note: candidate expects 2 arguments, 5 provided
This is just half of the errors, below i have all the .h files and a link to a1test.cpp (its a long code)
EAN.h
bool isValid(const char* str);
bool isRegistered(const Prefix* p, const char* str, char area[],char publisher[], char title[]);
GS1Prefix.h
const int MAX = 700;
struct Prefix {
int no; // number of entries
int area[MAX]; // area elements
char pubLow[MAX][8]; // low end of publisher range
char pubHgh[MAX][8]; // high end of publisher range
int pubLen[MAX]; // no of chars in publisher string
};
bool load(const char* filename, Prefix* p);
bool isRegistered(const Prefix* p, int area);
int minNoDigits(const Prefix* p, int area);
bool isRegistered(const Prefix* p, int area, const char* publisher);
Link to a1test.cpp ->a1test.cpp
UPDATE: As suggested by remyabel, i made #include "GS1Prefix.h" after #include "EAN.h"
In file included from EAN.cpp:6:0:
EAN.h:3:25: error: âPrefixâ does not name a type
EAN.h:3:33: error: ISO C++ forbids declaration of âpâ with no type [-fpermissive]
Simply switch the order of your headers and your code should compile fine. Because you did not provide GS1Prefix.cpp and EAN.cpp I cannot comment on the rest of the errors (if there are any left.)
#include <cstring>
// GS1Prefix.h
const int MAX = 700;
struct Prefix {
int no; // number of entries
int area[MAX]; // area elements
char pubLow[MAX][8]; // low end of publisher range
char pubHgh[MAX][8]; // high end of publisher range
int pubLen[MAX]; // no of chars in publisher string
};
// EAN.h
bool isValid(const char* str);
bool isRegistered(const Prefix* p, const char* str, char area[],char publisher[], char title[]);
// a1test.cpp
bool load(const char* filename, Prefix* p);
bool isRegistered(const Prefix* p, int area);
int minNoDigits(const Prefix* p, int area);
bool isRegistered(const Prefix* p, int area, const char* publisher);
// .. rest of your file
Header files should include sufficient definition so that they are self-sufficient. In this case you need to supply a definition of the requisite type, Prefix. Just add the include to the top of EAN.h:
#include <GS1Prefix.h>
bool isValid(const char* str);
bool isRegistered(const Prefix* p, const char* str, char area[],char publisher[],
char title[]);
Then you can include EAN.h in any source file knowing that you don't have dependencies to worry about.