MD. Khairul Basar
MD. Khairul Basar

Reputation: 5110

Ambiguous behavior of variable declaration in c

i have the following code

#include<stdio.h>
int main()
{
    int a12345678901234567890123456789012345;
    int a123456789012345678901234567890123456;
    int sum;

    scanf("%d",&a12345678901234567890123456789012345);
    scanf("%d",&a123456789012345678901234567890123456);
    sum = a12345678901234567890123456789012345 + a123456789012345678901234567890123456;
    printf("%d\n",sum);

    return 0;
}

the problem is, we know that ANSI standard recognizes variables upto 31 characters...but, both variables are same upto 35 characters...but, still the program compiles without any error and warning and giving correct output...
but how?
shouldn't it give an error of redeclaration?

Upvotes: 6

Views: 1216

Answers (5)

effeffe
effeffe

Reputation: 2891

[...] we know that ANSI standard recognizes variables upto 31 characters [...] shouldn't it give an error of redeclaration?

Well, not necessary. Since you mentioned ANSI C, this is the relevant part of C89 standard:

"Implementation limits"

The implementation shall treat at least the first 31 characters of an internal name (a macro name or an identifier that does not have external linkage) as significant. Corresponding lower-case and upper-case letters are different. The implementation may further restrict the significance of an external name (an identifier that has external linkage) to six characters and may ignore distinctions of alphabetical case for such names.10 These limitations on identifiers are all implementation-defined.

Any identifiers that differ in a significant character are different identifiers. If two identifiers differ in a non-significant character, the behavior is undefined.

http://port70.net/~nsz/c/c89/c89-draft.html#3.1.2 (emphasis mine)

It's also explicitly described as a common extension:

Lengths and cases of identifiers

All characters in identifiers (with or without external linkage) are significant and case distinctions are observed (3.1.2)

http://port70.net/~nsz/c/c89/c89-draft.html#A.6.5.3

So, you're just exploiting a C implementation choice of your compiler.

Upvotes: 10

mafso
mafso

Reputation: 5553

A conforming implementation must support at least 31 characters for an external identifier (and your identifiers are internal, where the limit is 63 for C99 and C11).

In fact, having all characters significant is the intent of the standard, but the committe doesn't want to make implementations non-conforming by not providing it. The limits for external identifiers origin from some linkers unable to provide more (in C89, only 6 characters were required to be significant, which is why the old standard library functions have names not longer than 6 characters).

To be precise, the standard doesn't exactly mandate these limits, the language in the standard is quite permissive:

C11 (n1570) 5.2.4.1 Translation limits

The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits:18)

  • [...]
  • 63 significant initial characters in an internal identifier or a macro name (each universal character name or extended source character is considered a single character)
  • 31 significant initial characters in an external identifier (each universal character name specifying a short identifier of 0000FFFF or less is considered 6 characters, each universal character name specifying a short identifier of 00010000 or more is considered 10 characters, and each extended source character is considered the same number of characters as the corresponding universal character name, if any)19)
  • [...]

Footnote 18) clearly expresses the intent:

Implementations should avoid imposing fixed translation limits whenever possible.

Footnote 19) refers to Future language directions 6.11.3:

Restriction of the significance of an external name to fewer than 255 characters (considering each universal character name or extended source character as a single character) is an obsolescent feature that is a concession to existing implementations.

And to explain the permissiveness in the first sentence of 5.2.4.1, cf. the C99 rationale (5.10)

5.2.4 Environmental limits

The C89 Committee agreed that the Standard must say something about certain capacities and limitations, but just how to enforce these treaty points was the topic of considerable debate.

5.2.4.1 Translation limits

The Standard requires that an implementation be able to translate and execute some program that meets each of the stated limits. This criterion was felt to give a useful latitude to the implementor in meeting these limits. While a deficient implementation could probably contrive a program that meets this requirement, yet still succeed in being useless, the C89 Committee felt that such ingenuity would probably require more work than making something useful. The sense of both the C89 and C99 Committees was that implementors should not construe the translation limits as the values of hard-wired parameters, but rather as a set of criteria by which an implementation will be judged.

Upvotes: 3

Eklavya
Eklavya

Reputation: 18480

There is no limit . Actually there is a limit , it has to be small enough that it will fit in memory, but otherwise no . If there is a builtin limit (I don't believe there is) it is so huge you would be really hard-pressed to reach it. I generated C++ code with 2 variables with a differing last character to ensure that the names that long are distinct . I got to 64KB file and thought that is enough.

Upvotes: 2

user3920237
user3920237

Reputation:

The C89 rationale elaborates on this:

3.1.2 Identifiers

While an implementation is not obliged to remember more than the first 31 characters of an identifier for the purpose of name matching, the programmer is effectively prohibited from intentionally creating two different identifiers that are the same in the first 31 characters. Implementations may therefore store the full identifier; they are not obliged to truncate to 31.

The decision to extend significance to 31 characters for internal names was made with little opposition, but the decision to retain the old six-character case-insensitive restriction on significance of external names was most painful. While strong sentiment was expressed for making C ``right'' by requiring longer names everywhere, the Committee recognized that the language must, for years to come, coexist with other languages and with older assemblers and linkers. Rather than undermine support for the Standard, the severe restrictions have been retained.

Compilers like GCC may store the full identifier.

  • The number of significant initial characters in an identifier (C90 6.1.2, C90, C99 and C11 5.2.4.1, C99 and C11 6.4.2).

    For internal names, all characters are significant. For external names, the number of significant characters are defined by the linker; for almost all targets, all characters are significant.

Upvotes: 3

Zeiss Ikon
Zeiss Ikon

Reputation: 481

Many compilers are built to exceed ANSI specification (for instance, in recognizing longer than 31 character variable names) as a protection to programmers. While it works in the compiler you're using, you can't count on it working in just any C compiler...

Upvotes: 15

Related Questions