Redefinition Allowed in C But Not in C++

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 class S shall refer to the same declaration in its
context and when re-evaluated in the completed scope of S. 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 Foos 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



Leave a reply



Submit