I got a global object of type "unnamed-struct" and i'm trying to define it. I don't want to pollute my global namespace with such useless type (it will be used only once).
Global.h
extern struct {
int x;
} A;
Is there any correct way to define such object?
I was trying this:
Global.cpp
struct {
int x;
} A = { 0 };
But VS2012 throws "error C2371: 'A' : redefinition; different basic types". Thanks.
One possible solution: create another file Global_A.cpp that does not include Global.h, and define A there. By the equivalent-definition rule this will be valid, as long as the anonymous struct definitions are equivalent.
This is still a bad idea, and most compilers will warn about it e.g. (gcc): warning: non-local variable `<anonymous struct> A' uses anonymous type.
There is no way to do just this simply because it would be error prone: some time in the future someone (probably even you) may want to modify this structure's definition and he might forget to do this in the header and source files accordingly. So you will have to invent a name for this structure and use its name the source file and leave its definition up to the header.
I don't know if this helps you, and this my first post... So take it easy.
I just ran into this issue and what I did was I added a function that manipulates the struct to the file that contained the anonymous struct. That way I can call that function from any file in my project, and it manipulates the values in the struct for me.
Here is an example:
header.c has this anonymous struct:
struct
{
char line1[80];
char line2[80];
char line3[80];
} header;
I want to manipulate those values in "interface.c" because I am making a command line interface in another file. My first instinct was to use an extern, but it seems like adding the following function to header.c is just as good or better (Some people discourage the use of externs when avoidable).
void changeHeaders(char *one, char *two, char *three);
void changeHeaders(char *one, char *two, char *three)
{
strcpy(header.line1, one);
printf("\nHeader 1: %s", header.line1);
strcpy(header.line2, two);
printf("\nHeader 2: %s", header.line2);
strcpy(header.line3, three);
printf("\nHeader 3: %s", header.line3);
}
Now as long as I include the prototype for that function I can manipulate those struct variables from any file by using that function. Hope that helps someone.
Related
I have not been able to find an answer on this, but my case is:
// vulkan_glfw_backend.hpp
struct alignas(8) VulkanGlfwWindowContext;
class MY_API VulkanGlfwBackend
{
// [...]
private:
VulkanGlfwWindowContext* mpContext;
};
And the source file, where I want to have the implementation:
// vulkan_glfw_backend.cpp
#include "vulkan_glfw_backend.hpp"
struct VulkanGlfwWindowContext
{
int numWindows;
GLFWwindow* windows[MAX_WINDOWS];
};
Initially, my compiler complained because it couldn't determine the alignment requirements for the class, which I suppose makes sense. Then I added the alignas attribute. But now I get an error message, which I cannot understand the logical reason for:
vulkan_glfw_backend.cpp:113:51: error: invalid use of incomplete type ‘struct VulkanGlfwWindowContext’
113 | for (int i = 0; i < mpContext->numWindows; i++)
Since I declare it explicitly as a pointer inside a class, the storage requirements should be clear. Additionally, it's an implementation detail how the memory layout of the struct looks, which the compiler knows at compile-time, because it is defined at the top of the source file.
So, why is this going wrong, and can I fix it somehow? For several reasons I desire to have an opaque type. Thanks!
Answering my own question :)
So this is one of those days, where I'm not completely posting the entire code as is (my apologies!). So, the entire thing is inside a namespace:
// header
namespace mynamespace
{
// vulkan_glfw_backend.hpp
struct alignas(8) VulkanGlfwWindowContext;
}
//source
#include "vulkan_glfw_backend.hpp"
using namespace mynamespace;
struct VulkanGlfwWindowContext
{
int numWindows;
GLFWwindow* windows[MAX_WINDOWS];
};
The reason for this going wrong - again, I don't understand the logics behind it. Anyways, this is the fix:
//source
struct mynamespace::VulkanGlfwWindowContext
{
int numWindows;
GLFWwindow* windows;
};
Apparently, C++ doesn't understand the definition without fully-qualified namespace prepended to the name. I have seen the same issue with functions - it is not enough to open the namespace, it must be included in the definition.
This confuses me, as it is not required when implementing class member functions, where the name of the class is sufficient, e.g. someclass::somemember() {}.
But it works now!
I am attempting to separate my function prototypes and the actual implementantions between .h and .c files to make it easier to see what functions I have.
my compiler, visual studio, has removed the curly green underline from under the function prototypes in the header files implying it is seeing the implementations in the .c file, but when I try to compile it I get 100+ errors all saying stuff like "syntax error: missing ';' before '*'" or "syntax error: missing ')' before '*'" or "syntax error: missing '}' before '*'" both in the .h and .c files. They are mostly pointing to the parameters in the prototypes, but I could not go trough all to know for sure.
Is there some other special way to do this?
I tried:
Making them extern
Changing guards to a name i know for sure isnt already used
I do not know what else I can try.
The first thing you could try is posting your code so we can see it :-)
However, the error syntax error: missing ';' before ... almost always shows up because you have an unknown type, as per the following:
int main() {
NOTYPE *x;
return 0;
}
Since you're moving function prototypes into a header, it may be that they're using types that still exist in the C file. Those type declarations must exist before use, or you will get that error.
That (function prototypes with unknown types) is not the only reason that error occurs but I can almost guarantee it'll be a similar issue, trying the use a type not yet declared.
As per other information posted here, you can also get this problem with circular dependencies, such as with:
typedef struct { TWO *two; } ONE; // don't know anything about TWO here.
typedef struct { ONE *one; } TWO;
If the dependency was only one way, then you could just ensure the order of the two definitions was correct. With a circular dependency, you have to introduce an incomplete definition (really a declaration) to allow it to work:
typedef struct TWO; // declare that TWO exists.
typedef struct { TWO *two; } ONE; // define ONE, we know TWO exists.
typedef struct { ONE *one; } TWO; // define ONE, we know all about ONE.
Note that this only works if you declare a pointer to the incomplete type, you won't be able to do:
typedef struct TWO;
typedef struct { TWO two; } ONE;
because the definition of ONE requires a complete type.
I have figured out the error.
The problem was that I had a circular dependency with 2 structures and I tried to fix it by defining them both before implementing them, but that obviously did not work.
this was my code:
typedef struct A;
typedef struct B;
typedef struct {
B* blist;
}A;
typedef struct {
A* a_parent;
}B;
The following stackoverflow answer helped me fix my errors:
Resolve circular typedef dependency?
I want to Use one globe variable in all cpp files.If one class of the cpp file changed the value,I want to access it from another class cpp file,which is the value that least modified by any other cpp class file.
str.h - global variable file
#ifndef MY_PROG
#define MY_PROG
extern char * myname;
#endif
class1.cpp
#include "str.h"
char * myname;
class class1
{
class1(){}
~class1(){}
void Setname1(char *name) { myname = name }
};
class2.cpp
#include "str.h"
char * myname;
class class2
{
class2(){}
~class2(){}
void setName(char *name) { myname = name }
};
class3.cpp
#include "str.h"
class class3
{
class3(){}
~class3(){}
char *GetData()
{
return myname;
}
};
main.cpp
#include "str.h"
int main()
{
class1 c1;
class2 c2;
c1.Setname1("XXXX");
c2.setname("YYYY");
class3 c3;
cout << c3.GetData;
}
when I execute the program, I need to get Last modified value that is "YYYY" .I am new to cpp, And also please tell me whether I used the extern keyword correctly.If not , please provide me the right procedure.
The essential in your problem is understanding the difference between declarations and definitions of variables (and types, functions etc. objects in C/C++)
extern char * myname; is a declaration. It makes myname visible to other pieces of code in the same file so that they can reference it.
char * myname; is a definition. Not only it makes myname visible, it also instructs the compiler to allocate space for it and to make its address known.
You can have as many declarations of the same variable in your code as you want, as long as they do not contradict each other. No so with definitions. If you define a thing two times, it would need to be assigned two addresses, and then how can other object files "understand" which address to use when referencing it? The same goes with the space allocated — what to do with the extra piece of it allocated? This is the error that you see.
To make the code work, have only one and exactly one definition of myname in exactly one file. It must not be a header file because it gets copied into multiple source files thus creating multiple definitions. It can be any other C++ file though.
In the rest of the files (or in a single header included in all of them) have multiple declarations of myname if it is referenced in a particular file. If not, you can omit it for a particular unit.
All this being said, it is considered to be a VERY BAD PRACTICE to communicate data between compilation units through global mutable shared variables. They make code a nightmare to debug and understand and impossible to parallelize. Nobody ever thinking getting money for the code they write should use them. Instead, the best approach would be to pass a mutable object as one of methods/functions argument. Details actually depend on the rest of your application.
I'm new to doing structs, so please bear with me if this turns out to be a dumb question. I have one header file and four .cpp files that all include it. I have a struct called ToDoLista and it has string nameIt and int DeadLine. Then I have the things whose type name I don't know that are like, the Soccer and DropOffMax and stuff.
ToDoLista Soccer, DropOffMax, CookDinner;
Soccer.DeadLine=6;
Soccer.nameIt="SOCCER";
//and so on, for a total of six, 3 ints and 3 strings definitions.
This struct seems to be finnicky if I try to move it around because if it's in the header it's included three times and it wont run due to 'multiply defined' whatever. If I put it in one of my three non-main cpp files, it seems that the struct won't work because some of it has to be defined in main(). So now it's in my main cpp file, but I have functions that use these values, and those functions are in my non-main cpp files, which as far as I know compile before the main one. To get around that, I put the struct declaration in the header, and the definitions in my main (I may have mis-worded that) AND THEN I say 'okay, run the function 'CheckItTwice'.
//MAIN
Soccer.DeadLine=6;
//and so on for all six, like before.
//ok, NOW run the fx.
CheckItTwice(Soccer.Deadline, Soccer.nameIt);
The issue here is that if I tell CheckItTwice to say, cout the string, or the int, it runs the program without errors, but returns nothing in the console where the cout should be, because apparently they haven't been defined yet, as far as the function is concerned. Why is this/do you know a way around this?
In order to avoid the "defined multiply" errors you need to define your struct in a header file, and put a #pragma once or #ifndef...etc block at the top. See this here.
Include the header file in any implementation (cpp) file you plan to use the struct in.
The line
ToDoLista Soccer, DropOffMax, CookDinner;
declares three instances of the struct ToDolista, called Soccer, DropOffMax, and CookDinner. They are not types, they are instances of a type, that type being ToDolista.
I can't comment on the contents of CheckItTwice() as you didn't provide them, but look here for guidance on using cout. You might want to consider passing the struct as one argument to this method, preferrably as a const reference.
Define the struct in your header and #include that header in the cpp files. In the header try adding
#pragma once
at the top of your header file. This is a Microsoft specific extension - documented here
The more portable version is to add
#ifndef _SOME_DEF_
#define _SOME_DEF_
struct ToDoLista {
string namit;
string project;
int status;
int speed;
int difficulty;
int priority;
int deadline;
}
#endif // _SOME_DEF_
Be sure to remove struct definition from the .cpp file.
I got this issue resolved using something I saw while searching desperately online: extern. it seems that if I put the declaraction in the header, the definition in a cpp, and then declare the object again in another cpp but with 'extern' before it, it works like a charm as far as keeping the values from the original definition.
Header.h
struct ToDoLista{
string namit;
string project;
int status;
int speed;
int difficulty;
int priority;
int deadline;
};
Side.cpp
ToDoLista Pushups, Tumblr, Laundry, CleanRoom, CleanHouse, Portfolio;
void CheckItTwice(int staytus, string name){
if(staytus==1){//not on the list
staytus==2;
cout << "hurry up and" << name << " okay?" << endl;
Main.cpp
extern ToDoLista Pushups, Tumblr, Laundry, CleanRoom, CleanHouse, Portfolio;
Pushups.namit = "Push Ups";
Pushups.status = 1;
Pushups.speed = 0;
Pushups.difficulty = 0;
Pushups.priority = 0;
Pushups.project = "Get Fit";
Pushups.deadline = 20131102;
CheckItTwice(Pushups.status,Pushups.namit);
This works for me, and I hope this 'answer' helps someone else.
The following sketch to fails to compile in the Arduino environment.
Given that typedefs can be used within Arduino software, is Automatic Prototype Generation the underlying mechanism that causes the failure? If so, what is it and why isn't Arduino providing a lightweight wrapper around C++?
#define PRODUCE_WACKY_COMPILETIME_ERROR
typedef int MyMeaningfulType;
#ifndef PRODUCE_WACKY_COMPILETIME_ERROR
void myFunc(MyMeaningfulType myParam);
#endif
void myFunc(MyMeaningfulType myParam)
{
myFunc(10);
}
void setup() {}
void loop() {}
For the benefit of the search engines, the errors reported are:
error: variable or field 'myFunc' declared void
error: 'MyMeaningfulType' was not declared in this scope
Please refer to http://arduino.cc/en/Hacking/BuildProcess the specific quote is:
This means that if you want to use a custom type as a function argument, you should declare it within a separate header file.
This page does a good job of explaining how the Arduino Language is different from C/C++ in how it works/pre-processes files.
They are attempting to create prototypes for every function they find. Unfortunately, if you define a typedef in the file before the function, and use that in a function definition, the place they put the function prototype does not see it, and this generates a syntax error.
If you use the 'struct * ' syntax instead in those function definitions, you benefit from C's 'opaque type' facility, in which you can use a struct definition without having it be declared beforehand. So, build the typedef, use it, but use the struct definition in any functions that use the typedef in arguments.
typedef struct mytype_ {
int f1;
} mytype_t;
void myfunc(struct mytype_ * xxx) {
xxx->f1 = 1;
}