C ONE LINER

C

CBFalconer

Keith said:
Keith Thompson said:
As recently as gcc 4.3.2 on Ubuntu, "unix" *is* predefined as
a macro with the value 1. I've never heard of ti being an
implicitly declared automatic variable.
[...]

Sorry, I meant to mention that "-ansi" turns this off. (And
as long as I'm correcting myself, "ti" should be "it".)

I imagine "-std=c99" will also shut it off.
 
C

Chris M. Thomasson

Can you determine output of following one liner by visual inspection..
It had won an award in obfuscated C contest.....

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0×60);}

You can also list your favourite one liner...


Where is:

#include <stdio.h>

?
 
C

Chris M. Thomasson

Chris M. Thomasson said:
Can you determine output of following one liner by visual inspection..
It had won an award in obfuscated C contest.....

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0×60);}

You can also list your favourite one liner...


Where is:

#include <stdio.h>

?

Implicit.
 
N

Nate Eldredge

Andrey Tarasevich said:
I got it from here

http://www.di-mgt.com.au/src/korn_ioccc.txt

I have to admit that haven't noticed that this is not really IOCCC web
site at all. Quite possibly the explanation given at that page is
incorrect. It seemed pretty authentic to me and it made sense, at
least at the first sight. Now I wonder if this can actually work,
given the right OS.

Was it ever possible to implicitly declare *variables*? K&R I makes
mention of implicitly declaring *functions* (A.13), but not variables.

Regarding whether "unix" would have been a macro, I had a look at the
4.3BSD sources, which would have been current in 1987 when that entry
was written. I can't find any place where a "unix" macro gets
automatically predefined, but it's possible I'm missing something.
There are "#ifdef unix" in a number of places. The Makefile for
compiling cpp itself contains -Dunix=1, but I didn't find that anywhere
else.

V7 UNIX has a similar situation.
 
N

Nate Eldredge

Andrey Tarasevich said:
BTW, why did the original author put a pair of braces around 'unix' in
(unix)["have"]+"fun"-0x60'?

I assume it was to make it look like a cast.

(Language barrier: to me, these characters ( ) are parentheses. Braces
are these { } . These [ ] are brackets.)
 
N

Nate Eldredge

Richard Heathfield said:
Chris M. Thomasson said:
Chris M. Thomasson said:
Can you determine output of following one liner by visual inspection..
It had won an award in obfuscated C contest.....


main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0×60);}


You can also list your favourite one liner...


Where is:

#include <stdio.h>

?

Implicit.


No, you were right the first time. It's missing. The behaviour of the
program is consequently undefined (calling a variadic function without a
valid function prototype in scope). A certain degree of latitude is often
granted to IOCCC programs that would not be acceptable in a production
environment. IOCCC is, after all, supposed to be a refuge for abused C
code, n'est ce pas?

Further allowances should be made for the fact that the code in question
is from 1987, pre-C90, and the rules only asked for the code to conform
to K&R ("plus common extensions"). Under K&R C, the use of printf would
create the implicit declaration `extern int printf();' which would
suffice.

So the inclusion of stdio.h is not implicit, but the only relevant
declaration that it contains, is.
 
M

Michael

Can you determine output of following one liner by visual inspection..
It had won an award in obfuscated C contest.....


main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0�60);}


You can also list your favourite one liner...
There is no #include<stdio.h>
It will generate a compilation error saying printf is not defined.
 
D

Dik T. Winter

> I got it from here
>
> http://www.di-mgt.com.au/src/korn_ioccc.txt
>
> I have to admit that haven't noticed that this is not really IOCCC web
> site at all. Quite possibly the explanation given at that page is
> incorrect.

That explanation is bogus. Originally you could omit the *type* from
the declaration (it defaulted to int) but you could not omit the complete
declaration, moreover, there should also be a keyword that made it appear
as a declaration. So:
auto unix;
was allowed (it defaulted to int), but plain:
unix;
not, and complete omission also not.

And by the time of that IOCCC omitting the type was also no longer allowed.
> It seemed pretty authentic to me and it made sense, at least
> at the first sight. Now I wonder if this can actually work, given the
> right OS.

The program as given (with "int unix;" added) did indeed work with Unix
on the VAX.
 
D

Dik T. Winter

> No, you were right the first time. It's missing. The behaviour of the
> program is consequently undefined (calling a variadic function without a
> valid function prototype in scope).

That entry is from the IOCCC of 1987. At that time there was no such
requirement.
 
D

Dik T. Winter

> Regarding whether "unix" would have been a macro, I had a look at the
> 4.3BSD sources, which would have been current in 1987 when that entry
> was written. I can't find any place where a "unix" macro gets
> automatically predefined, but it's possible I'm missing something.
> There are "#ifdef unix" in a number of places. The Makefile for
> compiling cpp itself contains -Dunix=1, but I didn't find that anywhere
> else.

I think that predefines that macro for sources compiled with that cpp.
 
K

Keith Thompson

Dik T. Winter said:
That explanation is bogus. Originally you could omit the *type* from
the declaration (it defaulted to int) but you could not omit the complete
declaration, moreover, there should also be a keyword that made it appear
as a declaration. So:
auto unix;
was allowed (it defaulted to int), but plain:
unix;
not, and complete omission also not.
Agreed.

And by the time of that IOCCC omitting the type was also no longer allowed.

In 1987, there was no C standard, and I suspect most compilers allowed
"auto unix;" (unless they pre-defined "unix" as a macro, of course).

[...]
 
L

lawrence.jones

Nate Eldredge said:
Was it ever possible to implicitly declare *variables*?

Only parameters:

foo(i, j)
{
return i + j;
}

That implicitly declares i and j as int's.
 
L

lawrence.jones

Nate Eldredge said:
(Language barrier: to me, these characters ( ) are parentheses. Braces
are these { } . These [ ] are brackets.)

Yes, in other dialects they're all brackets: round brackets, curly
brackets, and square brackets, respectively. But I know of no dialect
in which the round ones are called "braces" as the original poster did.
Perhaps he was just using an unfortunate font. :)
 
A

Andrey Tarasevich

Only parameters:

foo(i, j)
{
return i + j;
}

That implicitly declares i and j as int's.

That's not what Nate's talking about. "Implicitly" in this case means
"without ever mentioning the variable's name in any declaration", as in

foo(i)
{
return a + b + i;
}

This was never possible (at least formally). So the linked explanation
is incorrect, although the idea with the storage for allegedly
implicitly declared 'int unix' overlaying the system-provided 'argc'
storage area had an undeniable perverted attractiveness.

As for the declarations that omit everything besides the name, some
older compiler would accept file-scope declarations without a storage
class and type name. I don't remember whether it was intended to be
legal in "C Reference Manual" times.
 
L

Lew Pitcher

[snip]
As for the declarations that omit everything besides the name, some
older compiler would accept file-scope declarations without a storage
class and type name. I don't remember whether it was intended to be
legal in "C Reference Manual" times.

As I read it, the "C Reference Manual" requires that declarations have
either a type specifier /or/ a storage class specifier /or/ both. But, you
cannot omit both type specifier and storage class specifier.

"8. Declarations
...
Declarations have the form

declaration:
decl-specifiers declarator-list{opt} ;

The declarators in the declarator list contain the identifiers being
declared. The decl-specifiers consist of a sequence of type and storage
class specifiers.

decl-specifiers:
type-specifier decl-specifiers{opt}
sc-specifier decl-specifiers{opt}

8.1 Storage class specifiers
The sc-specifiers are

sc-specifier:
auto
static
extern
register
typedef

...
At most one sc-specifier may be given in a declaration. If the
sc-specifier is missing from a declaration, it is taken to be auto
inside a function, extern outside. Exception: functions are never
automatic.

8.2 Type specifiers
The type-specifiers are

type-specifier:
char
short
int
long
unsigned
float
double
struct-or-union-specifier
typedef-name

...
If the type-specifier is missing from a declaration, it is taken to be int.
"

--
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
 
W

William Hughes

Can you determine output of following one liner by visual inspection..
It had won an award in obfuscated C contest.....
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0×60);}
You can also list your favourite one liner...

I get the following when attempting to compile this code:

oneliner.c:1: warning: return type defaults to 'int'
oneliner.c: In function 'main':
oneliner.c:1: warning: implicit declaration of function 'printf'
oneliner.c:1: warning: incompatible implicit declaration of built-in
function 'printf'
oneliner.c:1: error: 'unix' undeclared (first use in this function)
oneliner.c:1: error: (Each undeclared identifier is reported only once
oneliner.c:1: error: for each function it appears in.)
oneliner.c:1: error: stray '\327' in program
oneliner.c:1: error: expected ')' before numeric constant
oneliner.c:1: warning: control reaches end of non-void function

So much for output.

The third symbol in "-0×60" is not an x by a times symbol, this is not
ascii.
What you get if you compile, depends on how you tried to copy the line
and how the compiler you use deals with non-ascii characters
When I did a cut and paste, I got the same errors with gcc 3.2.2

(a lot of error text for a "small" error. This reminds me of the
contest reported by Hofstadter IN GEB in which the smallest
<code text>/<error text> ratio was desired. Apparently the winner
was a single character "." which when fed to a COBOL compiler
produced pages of output)

- William Hughes
 
K

Keith Thompson

Eric Schmidt said:
Can you determine output of following one liner by visual inspection..
It had won an award in obfuscated C contest.....
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0×60);}
You can also list your favourite one liner...

I get the following when attempting to compile this code:

oneliner.c:1: warning: return type defaults to 'int'
oneliner.c: In function 'main':
oneliner.c:1: warning: implicit declaration of function 'printf'
oneliner.c:1: warning: incompatible implicit declaration of built-in
function 'printf'
oneliner.c:1: error: 'unix' undeclared (first use in this function)
oneliner.c:1: error: (Each undeclared identifier is reported only once
oneliner.c:1: error: for each function it appears in.)
oneliner.c:1: error: stray '\327' in program
oneliner.c:1: error: expected ')' before numeric constant
oneliner.c:1: warning: control reaches end of non-void function

So much for output.

The warnings are all about things that weren't necessarily considered
problems in pre-ANSI C. The errors are caused by (a) the fact that
you compiler doesn't pre-define "unix" as a macro, and (b) the
original poster's use of a multiplication symbol rather than a letter
'x' in 0x60.
 
N

Nate Eldredge

William Hughes said:
(a lot of error text for a "small" error. This reminds me of the
contest reported by Hofstadter IN GEB in which the smallest
<code text>/<error text> ratio was desired. Apparently the winner
was a single character "." which when fed to a COBOL compiler
produced pages of output)

Fun. I can't seem to find it in my copy of GEB, though.

I was thinking

a.c:
#error
#include "a.c"

would win with a ratio of zero. Unfortunately my compiler has a maximum
level of #include nesting, so I only get a ratio of 22/581994, or
~0.0000378. I suppose you might want to require the smallest *nonzero*
ratio anyway, by analogy with the busy beaver problem.
 
W

William Hughes

Fun. I can't seem to find it in my copy of GEB, though.


Well, my copy in not available at the moment. I am pretty
sure I saw this in GEB (an aside in amongst a discussion
of self replicating programs).
I was thinking

a.c:
#error
#include "a.c"

would win with a ratio of zero.



Nice. Perfectly within the spirit of GEB, too.

- William Hughes
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,787
Messages
2,569,631
Members
45,338
Latest member
41Pearline46

Latest Threads

Top