4

while studying a quine program in C, I found that, main was passed with just a, there is no datatype. The below runs fine and outputs the program correctly.

main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}

I would like to know, how does this work (not the actual quine program), but what is data-type of a? What value is it getting?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
mtk
  • 13,221
  • 16
  • 72
  • 112
  • Didn't you get warnings? The type defaults to `int` as others have pointed out. BTW, that program exhibits undefined behavior as you assign an `char*` to an `int`. – Spikatrix Aug 13 '15 at 14:26
  • @CoolGuy - the intent (and mistake) was that _a=%c%s%c_ was supposed to be enclosed in double quotes - `"a=%c%s%c"`. _That_ part at least did not compile, I'm pretty sure. – ryyker Aug 13 '15 at 14:57

3 Answers3

3

First, let me tell you, considering a hosted environment, the above code is non-standard and very bad way of coding, too. You should not write code like that.

This code, make use of the "default-to-int" property of legacy C. This property has been removed from the standard since C99. Compilers might be supporting and accepting this for legacy reasons.

Most probably, it used to get the value similar to that of argc.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
3

There is a difference between functions in general and main(), which is a special case.

For normal functions, the syntax you use would work in obsolete versions of C, where the types would be treated as "implicit int" and your function would become int func (int);. This nonsense feature was removed from the language 16 years ago and such programs will no longer compile.

As for the form of main(), there are some special cases, all described in detail with references in this answer.

TL;DR of that answer:

  • The form of main in your code is not allowed for a hosted C90 implementation.
  • It is not (most likely not, the standard is ambiguous) allowed for any other hosted C implementation either.
  • The code could be valid for some obscure freestanding implementation. Yet the code doesn't make sense in such a context.
  • Or most likely: the code is non-standard and will not compile on any conforming compiler at all.
Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    Terminology glitch: there's no such thing as a strictly conforming *compiler*; conformance, strict or not, is a property of *programs*. – Jens Aug 13 '15 at 14:35
  • @Jens - I am curious what phrase would you use to describe a compiler that includes non-standard or _non-portable_ features?, (for example GCC with all of its non-standardized extensions). Phrases like _strictly conforming_, or _loosely conforming_ seem clear in their meaning. – ryyker Aug 13 '15 at 14:54
  • 1
    @Ryyker: Since all compilers allow extensions, it is really pointless to invent a name that matches any compiler. Conformance as defined by the C Standard has a very precise meaning. Did you know that you'll have a hard time even writing a strictly conforming hello world program? "It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit." There is, however, the concept of a *conforming implementation* (one which accepts any strictly conforming program). – Jens Aug 13 '15 at 15:04
1

what is data-type of a?

It's an int. This is a legacy of the olden days when C objects were considered to be int unless explicitly stated.

What value is it getting?

This is a more tricky question. What is being attempted is to assign the address of the format string to a. In olden days, people often used to assign pointers to ints and vice versa. However, there has never been a rule to say sizeof(char*) == sizeof(int) and, indeed, on my compiler (clang 7) a char* is 8 bytes while an int is a mere 4 bytes. This is why your program compiles (with six warnings) but seg faults when I run it.

JeremyP
  • 84,577
  • 15
  • 123
  • 161