What is meant by 'data variable'? - c++

What does 'data variable' mean in MSVS2010 in this error? I thought I was declaring a symbol that is defined elsewhere in my code.
error C2365: 'g_surf' : redefinition; previous definition was 'data variable'
Obviously this could mean an int or char.
I followed a working example.
I had to include a definition of the class before declaring the symbol.
#include classdef.h
I used the extern keyword to declare an object in stdafx.h.
extern COriginal g_orig;//works
extern CClass g_surf;//how is this declaration resulting in a 'data variable' type?
I instantiate a class in a code file (in global space). This is where the error occurs.
COriginal g_orig(CONST_ARGUMENT);//works
CClass g_surf();//seen as redefinition.
I created a class from two other classes because I need attributes from both.
I can find other redefinition questions that do not offer insight to this one. I haven't found in MSVS2010 or on the web what is meant by 'data variable'.

You probably meant to call a constructor with no parameters.
CClass g_surf;
For your compiler, this line
CClass g_surf();
is the forward declaration of a method called g_surf taking no parameters and returning a CClass.

'Data variable' does appear to include symbols declared with class types.
So, I was trying to redefine the type of the symbol to something else.
I was trying to use the same symbol to declare a function.
The mistake I was making in my code was adding parenthesis on the symbol name when instantiating a class.

Related

C++ why we include all declarations in header files

#include <iostream>
When you do this and it becomes the source passing through the preprocessor, our file will be 5k. The compiler doesn't do all this declaration, right? (There are always some things we don't use after all)
| Is the linker or compiler preventing this?
**so when you include all declaration file in header **
improve build times.
link against code without having the source for the definitions.
avoid marking everything "inline".
compiler only see the declaration as it know definition might be somewhere , then it use all definition at the linking time.
The rule of thumb is this: Header files should contain declarations, source files should contain definitions.
Two types of Declarations:
DECLARATIONS: A declaration introduces a name into a scope. Generally speaking, a scope is either an entire .cpp file or anything in code delimited by {}, be it a function, a loop within a function, or even an arbitrarily placed block of {} within a function. A name introduced, is visible within the scope from the point at which it is declared to the end of that scope. A declarations merely tells the compiler how to use something, it does not actually create anything.
extern int y; // declares y, but does not define it. y is defined elsewhere,
// but the program can now use it since it knows what it is (an integer)
PROTOTYPES: A prototype is just another name for a declaration of a function.
double someFunction( double, int );
referred from :
http://www.cplusplus.com/articles/yAqpX9L8/
Also get more information on this site:
http://www.cplusplus.com/articles/Gw6AC542/

"Multiple definition of.." "First defined here" in the same line in a data structure

I have read many posts before posting this one, I couldnt find a solution because non of them (those I read) were on data structures.
I have two data structures (If it matter, a Heap and a UF).
Both of them are implemented in the .h file.
I'm getting the "Multiple definition of.." "First defined here" errors only on member functions implemented outside of the class (such as int UnionFind::Find(int i) )
It happens for the c'tors and d'tors also, but when I implement them in the class itself, it disappear.
I really have no clue why it is happening.
I have followed the includes in all of my files and there are no double includes or loops.
I'm also using an AVL tree, and it does not happen there, everything there is implemented in the .h file outside of the class.
These are the errors im getting :
/tmp/ccp8fP73.o: In function `UnionFind::Find(int)':
main.cpp:(.text+0x0): multiple definition of `UnionFind::Find(int)'
/tmp/ccVxSiPy.o:Elections.cpp:(.text+0x0): first defined here
/tmp/ccp8fP73.o: In function `UnionFind::Union(int, int)':
main.cpp:(.text+0x108): multiple definition of `UnionFind::Union(int, int)'
/tmp/ccVxSiPy.o:Elections.cpp:(.text+0x108): first defined here
If you need more info, please tell me.
Thank you
If I understand you correctly, you are doing things like this:
// C.h
class C
{
void f(); // declaration of f; ok to include in many modules
};
// definition of f; must not exist in more than one module
void C::f()
{
}
That doesn't work because the definition of f() will wind up in every module that includes C.h, leading to exactly the linker error you describe. You can fix this by either marking f() as inline, or by moving the definition of f() to a separate cpp file.
There is one special case where this is allowed, and that's when f() is a template (either directly or because C is a template). In that case, the definition must be in the header so the compiler can know how to instantiate it for whatever type(s) you specify. This does make life difficult for the linker since you can and often do end up with the sorts of redundant definitions that would normally be errors (e.g if you use f<int>() in more than one module). Special behavior is needed to handle this.
Incidentally, the reason things work when you move the function bodies inside the class definition is because that has the effect of making them implicitly inline.
If you want to create your templates manually..
//1. include the template code..
#include <template/list.tmpl.c>
// 2. instantiate the instances that use it..
#include "/c/viewer/src/ViewObject.h"
#include "/c/viewer/src/WindowAdaptor.h"
template class List<ViewObject>;
template class List<WindowAdaptor>;

Does not name a type error is due to existing enum, but why?

I was just getting this error: "error: ‘Symbol’ does not name a type"
I found some other StackOverflow questions talking about circular dependencies, but that is not the case here. In fact I could reproduce it by putting this at the top of the source file:
class Symbol{int dummy;};
//class Symbol{int again;};
Symbol global_symbol;
This gives "error: ‘Symbol’ does not name a type" for the 3rd line. If I uncomment the 2nd line, I still get that same error, but just before it I now get: "error: redefinition of ‘class Symbol’" !!
After lots more poking around it appears a 3rd party library has an enum where Symbol is defined. Neither that library, nor my own code, uses namespaces, so as moving my code to be inside a namespace was already on my to-do list I'll do that next and hopefully the problem will go away.
But what confuses me is why I didn't get an error on the class Symbol{} line? If it clashes with an enum, to the extent that I would never be able to instantiate that class, why didn't it complain? I feel like I'm either missing a flag for g++, or there is a gap in my C++ knowledge. I'm bracing myself for someone to tell me this is a feature not a bug.
(BTW I am using g++ -c -std=gnu++0x -Wall -g -Werror ... and g++ 4.8.1)
What you are seeing is a form of name hiding: a declaration of an variable or function Symbol will be found in preference to class Symbol ([basic.scope.hiding] §3.3.10/2). In the cases where C++ allows one declaration to hide another in the same scope, there is always an elaborated-type-specifier which still refers to the hidden declaration. They are so named because only a type (class or enum) may be hidden in this way; typedefs and templates cannot. The order of declaration is not significant.
In this case, you can use class Symbol to refer to the class when the variable or function is in scope:
class Symbol global_symbol;
gcc error messages are not the most user friendly, due to the fact that C++ has quite a complicated syntax and the parser sometimes gets totally confused by the smallest error, such as a missing ;. For example, your code of the form
enum A{Symbol=0};
class Symbol{int dummy;};
int main()
{
Symbol global_symbol;
}
where an enum having a Symbol is declared before the class Symbol gives me the following compiling error (I use g++4.8):
minimal.cpp: In function 'int main()':
minimal.cpp:13:9: error: expected ';' before 'global_symbol'
Symbol global_symbol;
^
minimal.cpp:13:22: warning: statement has no effect [-Wunused-value]
Symbol global_symbol;
So the best thing to do is to use namespaces in your code, or change the class name :)
And you mentioned you used g++2.8. You meant 2.8 or 4.8? 2.8 is quite antique (16 years old), so it's not even fully C++98 compliant.

Link error when adding array to common functions class

I have a common functions class. Basic stuff, just has functions several classes in my project can use. But i am trying to add an array of structs so that several classes can use them for some things. Ive removed this array of structs from another Class (Class 1) and added them to my CommonFunctions class. They are only going to be read.
But Im getting errors:
CommonFunctions.obj : error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in Class1.obj
error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in Class1.obj
fatal error LNK1169: one or more multiply defined symbols found
Then for every other class in the project (which uses the CommonFunctions class, so all of them really) I get
error LNK2005: "struct pup_file * pups" (?pups##3PAUpup_file##A) already defined in main.obj
Anyone help me with whats going on here?
It looks like you didn't declare the pointer pups (it's not an array) inside the class definition.
If you put it in the header but outside the class, you would get errors like those.
The solution is to make sure that pups is declared inside the CommonFunctions class definition.
After reading your comment on making it a static you probably want to define it as an extern rather than static as static means that everything that includes that definition gets its OWN copy (ie the copy is not shared between all of the files that include it).
Extern means that you will need to define it in a c/cpp file somewhere but you must only define it once and then any compilation unit that includes that extern will use the same structure.
Of course you might actually want each compilation unit to have its own copy of the variable and in which case static is what you want.

C++ previous definition error

So, thanks to this website, I found the answer to my previous problem. I'm adding a function to a class in a GNU automake project that uses a pointer to a doc object. Dependencies were included in the Makefile.am file to include doc.h and plsa.h in the respective order. However, when I compiled, I would get a doc has not been declared error. Then, I tried adding the #include statement here, which gives a previous redefinition of 'class doc' error.
I learned that I have to declare doc by using the class doc; line commented out below; however, I thought that this was only necessary if I was declaring a function that passes the object by value. Can someone explain to me why the #include is incorrect in this case?
#include "doc.h"
//class doc;
class plsa {
// ...
int infer(doc *trset, int maxiter, double noiseH);
}
Why the Redefinition errors?
Please ensure that your header files have appropriate Header Guards/Include Guards.It is most likely that you have missed adding header guards and hence that causes multiple class definitions due to the header getting included multiple times.
Why Forward Declaration is okay in this case?
When instead of including the header file you add the line:
class doc;
It Forward declares the class doc which means for compiler it is an Incomplete type. With Incomplete types, One cannot create objects of it or do anything which needs the compiler to know the layout of docor more than the fact that doc is just an type.
i.e: The compiler does not know what are its members and what its memory layout is.
But Since pointers to all objects need just the same memory allocation, You can use the forward declaration when just reffering to an Incomplete type as a pointer.
In this case the only way in which doc is being referenced is an pointer to the class doc and hence the Forward declaration will work as well.
BottomLine:
Including the header file should work for you If you have proper Inclusion Guards in-place.
And there is nothing wrong with it.
However, Forward declaring the class should also work for you because of the reasoning given above.Note that forward declarations are usually used in case where there is a Circular Dependency of classes.
Which is better Include header File or Forward Declaration?
Including the header file just copy pastes the code from the header to wherever the file was included, which basically could lead to:
Increase in compilation time
Pollution of global namespace.
Potential clash of preprocessor names.
Increase in Binary size(in some cases though not always)
Forward Declaration has its own limitations on how the Incomplete type can be used further on.
With Incomplete type you can:
Declare a member to be a pointer or a reference to the incomplete type.
Declare functions or methods which accepts/return incomplete types.
Define functions or methods which accepts/return pointers/references to the incomplete type (but without using its members).
With Incomplete type you cannot:
Use it as a base class.
Use it to declare a member.
Define functions or methods using this type.
Given the possibility(due to above limitations on Incomplete type usage) One should prefer Forward Declaration over Including Header.
You are missing include guardians. if you just include files they are just pasted you need to make sure when they are included multiple times that they other times the code isn't duplicated. so you use a construct like this.
#ifndef _XXX_
#define _XXX_
/* your header here */
#endif