Redefinition allowed in C but not in C++?
Tentative definition is allowed in C but not in C++.
A tentative definition is any external data declaration that has no storage class specifier and no initializer.
C99 6.9.2/2
A declaration of an identifier for an object that has file scope without an initializer, and
without a storage-class specifier or with the storage-class specifier static, constitutes a
tentative definition. If a translation unit contains one or more tentative definitions for an
identifier, and the translation unit contains no external definition for that identifier, then
the behavior is exactly as if the translation unit contains a file scope declaration of that
identifier, with the composite type as of the end of the translation unit, with an initializer
equal to 0.
So int i
is a tentative definition. The C compiler will combine all of the tentative definitions into a single definition of i
.
In C++ your code is ill-formed due to the One Definition Rule (Section 3.2/1 ISO C++)
No translation unit shall contain more than one definition of any variable, function, class type, enumeration type or template.
// but if I write
int i = 5;
again I get error in C also
Because in that case it no longer remains a tentative definition because of the initializer (5).
Just for the sake of information
J.5.11 Multiple external definitions
There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern; if the definitions disagree, or more than one is initialized, the behavior is undefined (6.9.2).
Also check out this excellent post on external variables.
how to solve type redefinition error in this C program
No Need to define 3 times
struct point {
int x;
int y;
} p1;
struct point {
int x;
int y;
} p2;
struct point {
int x;
int y;
} p3;
define only once, and create variables as you wish.
struct point {
int x;
int y;
};
struct point p1,p2,p3;
I am getting an error of redefinition while using extern header file
There are definitions and declarations. A declaration tells the compiler that something exists. A definition is a declaration that has all the information needed to describe that thing.
For global variables like maxid
, The extern
says that it will have external linkage; that is, be known to the linker and be seen between different source files (translation units).
Many different translation units can say extern int maxid;
and they all just say "OK, I know about this symbol, I'll find it somewhere eventually.". So, that's fine to put in a header which becomes part of more than one translation unit.
However, when you give it an initializer, in this case the =0
(one of several possible ways describe initialization), then it becomes a definition
. It causes storage to be allocated and a definite location set up for that variable. You should not do that in a header, because each file that includes it will define the same variable. Thus, at link time you get more than one, which is an error.
The legacy way of doing this is to put extern int x;
in the header so that everyone knows x
exists, and then put int x = 0;
in one CPP file so that this variable lives somewhere. Writing extern int x = 0;
would mean the same thing but is un-idiomatic.
The modern way to handle this is to use a feature created for this express purpose. Put inline int x = 0;
in the header file. This will define it in every translation unit that includes it, but they will be marked such that the linker understands that they are all the same and it should just pick one and ignore the others.
Redefinition of type in c, but guard is included?
Your guards protect against the same include file being included twice, but you have two different include files with two different guards, and you define cplx
in each one.
You need a separate guard for that type in each include file, like this:
#ifndef CPLX
#define CPLX
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
//declarations of functions
#endif
How can I redefine variables in C?
Replace int i = 100
with i = 100
.
You are not allowed to redeclare a variable in the same scope in C and C++. But you can set i
to a different value, which is what my change does.
Finally, if you want the final output of result
to be the sum of the new values of i
and j
, then you have to recompute. Put result = i + j;
just before the printf
call.
Redefinition error in c
The #undef Polygon
won't work because Polygon()
is a real function, not a macro. In Windows, that trick mostly works for functions that takes at least one string argument, because of the Unicode vs ANSI stuff.
If you only want the ShellExecute()
function you can omit all the GDI functions by defining NOGDI
before including Windows.h
:
#define NOGDI
#include <windows.h>
Alternatively you can add the NOGDI
macro to the preprocessor project options of your IDE.
Why can't redefine type names in class in C++?
This is not unique to types. [basic.class.scope]/2:
A name
N
used in a classS
shall refer to the same declaration in its
context and when re-evaluated in the completed scope ofS
. No
diagnostic is required for a violation of this rule.
The reason is that name lookup in class scope is a little special. Consider:
using Foo = int;
struct X {
Foo a; // ::Foo, i.e., int
void meow() {
Foo b = a; // X::Foo; error: no conversion from int to char*
}
using Foo = char*;
};
Name lookup in member function bodies considers all class members, whether declared before or after the member function (otherwise, a member function defined in a class definition wouldn't be able to use a data member declared later in the class). The result is that you get two Foo
s with different meanings, even though they both lexically precede the class member Foo
's declaration. This can easily lead to extremely confusing and brittle code, and so the standard bans it.
Related Topics
Linux C++: How to Profile Time Wasted Due to Cache Misses
Sharing Precompiled Headers Between Projects in Visual Studio
Clean Eclipse Index, It Is Out of Sync with Code
Creating Library with Backward Compatible Abi That Uses Boost
Enum VS Constexpr for Actual Static Constants Inside Classes
Calling a Constructor to Re-Initialize Object
How to Get File Extension from String in C++
Does an R Compiler to C/C++ Exist
Pass by Pointer & Pass by Reference
Is 1.0 a Valid Output from Std::Generate_Canonical
Why Sizeof Int Is Wrong, While Sizeof(Int) Is Right
Conversion from Boost::Shared_Ptr to Std::Shared_Ptr
C++ Metafunction to Determine Whether a Type Is Callable
Utilizing C++ in iOS and MAC Os X Applications