How to understand this line of c ?

T

tmp123

fidlee said:
Thanks for answering this question.That brings up my next question.
What is the significance of argv and argc in main() ?

Hi,

A full declaration of main is:

int main (int argc, char *argv[]);

That means:

1) main returns an integer. How the operating system, the caller shell,
or any caller interprets this result, is specific of the aplication.

2) The second parameter is an array of pointers to chars, or, in usual
language, an array of strings. Each item of the array is one parameter
of the call to the program. The number of used elements in the array is
stored in argc. The first element is typically the program name.

For example, if in a shell console you execute program "foo" typing:
foo 1 hello

means argc=3, argv[0]="foo", argv[1]="1", argv[2]="hello"

Kind regards.
 
F

fidlee

tmp123 said:
fidlee said:
Roberto said:
main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

can someone please explain as to what the initialization part of the
for loop does. How does the underscore '_' play a part in the for loop?
(in the initialization and the putchar function)?

Hi,

1) "_" can be the name of a variable. In this case, it is the name of
the first parameter of the function main (usually called argc). If the
program is called without arguments, it takes value 1. (to be
practical, I will rename it to "i").

2) This variable is used as iterator of the for statement. It is
decremented at init (it takes value 0) and increment at for continue
condition (++).

3) It is used as index to char string. Taken into account that:

a <==> *(a+b)

The expression i["1234"] <=> *(i+"1234") <=> "1234" : i-th character
of the string.

Hope this answer was useful to you.

Kind regards.


Thanks for answering this question.That brings up my next question.
What is the significance of argv and argc in main() ?
 
J

John Bode

tmp123 said:
lnzju said:
main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}

[snip]

* integer applied to string returns n-th element. (this is something I
do not know why).

The expression a is defined as *(a+i); since addition is
commutative, it doesn't matter whether a is the pointer and i is the
index, or if i is the pointer and a is the index. Therefore, in C,
array indexing is commutative, so a and i[a] evaluate to the same
thing.

It's fun to explain this to Ada programmers and watch their heads
explode.
 
K

Keith Thompson

John Bode said:
The expression a is defined as *(a+i); since addition is
commutative, it doesn't matter whether a is the pointer and i is the
index, or if i is the pointer and a is the index. Therefore, in C,
array indexing is commutative, so a and i[a] evaluate to the same
thing.

It's fun to explain this to Ada programmers and watch their heads
explode.


Speaking as a long-time Ada programmer, I don't recall my head
exploding when I learned this. The explanation is perfectly clear,
but the rule is a bit silly. Nothing would have been lost by allowing
pointer+integer and forbidding integer+pointer.

I suppose it goes back to the days when C didn't make such a strong
distinction between pointers and integers.
 
R

Randy Howard

Jordan Abel wrote
(in article said:
And becomes a constraint error, not UB.

I repeat my original question, how many UB's does one need? I
never said the above was UB either.
 
D

Dik T. Winter

> Speaking as a long-time Ada programmer, I don't recall my head
> exploding when I learned this. The explanation is perfectly clear,
> but the rule is a bit silly. Nothing would have been lost by allowing
> pointer+integer and forbidding integer+pointer.
>
> I suppose it goes back to the days when C didn't make such a strong
> distinction between pointers and integers.

No, it goes back to the days when operators like "+" where commutative.
 
J

Jordan Abel

main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}
...
How many examples of UB must be present in order to obtain such
a license?

BTW, where is stdio.h?

Not needed for "putchar", that is not a variadic function.

Nor does it take any narrow (char, short, float) arguments or return a
type other than int, I assume you meant to add.
 
K

Keith Thompson

Dik T. Winter said:
No, it goes back to the days when operators like "+" where commutative.

Yes, when it denotes addition of numbers.

The "+" operator is usually commutative, but it usually takes two
operands of the same type. Commutativity makes less sense when the
operands are of different types.

Some languages use "+" to denote string catenation; in such a
language, "foo" + "bar" doesn't mean the same thing as "bar" + "foo".

In my opinion (and it's nothing more than that), the C language would
be cleaner if pointer+integer were allowed (as it is now) and
integer+pointer were disallowed (making index[array] illegal). I'm
not proposing that it should be changed now, since it would break
existing code. Allowing integer+pointer isn't particularly harmful,
but I don't think it's necessary.
 
I

Ivan Budiselic

Dik T. Winter said:
main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););} ...
Well it ain't rubbish cause it is valid C!!

Not really no.

What is wrong with it except the one argument main?[/QUOTE]

It seems you are arguing this is valid C because it contains "only one
undefined behavior". This is silly at best.

int main(void) {
int a;
++a;
return 0;
}

This has the same "amount" of UB, but I don't think you would argue that
it's valid C.

My original reaction was dismissive because I've noticed that novice
programmers start reading (and admiring, for some reason) obfuscated code
even before they learn how to write "normal" code, let alone robust quality
software. Reading and writing obfuscated code can maybe be a fun pastime,
but, for me at least, it's usually just disappointing - it has UB all over
the place most of the time.
 
D

Dik T. Winter

>
> Yes, when it denotes addition of numbers.

Not only then.
> The "+" operator is usually commutative, but it usually takes two
> operands of the same type. Commutativity makes less sense when the
> operands are of different types.

1 + 1.0 ?
> Some languages use "+" to denote string catenation; in such a
> language, "foo" + "bar" doesn't mean the same thing as "bar" + "foo".

As far as I know they came later than C. I think the first language
where it was possible that a + b was correct while b + a was not, was
Algol 68.
 
M

Markus Becker

Dik T. Winter said:
1 + 1.0 ?

or f(x)+g(y)?

Depending on what happens inside the function f or g, this
could mean anything.

Yes, and C uses '*' for pointer dereferencing. does that mean that in

int i,k;
int *p=&i;

the following should be equivalent:

k = *p; // and
k = p*; // ?
As far as I know they came later than C. I think the first language
where it was possible that a + b was correct while b + a was not, was
Algol 68.

Depending on a and b, it can be non-commutative even in C.
That's the reason why terms like 'oder of evaluation',
'operator precedence', 'sequence point', 'side-effects' etc. exist.

Programming languages are no math packages.

Markus
 
K

Keith Thompson

Markus Becker said:
or f(x)+g(y)?

Depending on what happens inside the function f or g, this
could mean anything.

(Missing attribution; I wrote the stuff starting with 'The "+"
operator is usually commutative'.)

What happens inside f() and g() obviously affects the result, but it
doesn't affect the meaning of the "+" operator; that's determined by
their declared return types.
Yes, and C uses '*' for pointer dereferencing. does that mean that in

int i,k;
int *p=&i;

the following should be equivalent:

k = *p; // and
k = p*; // ?

No, why would it? That's a unary operator; commutativity is
meaningless for it. The fact that it uses the same symbol as
multiplication is not significant. Unary and binary "*" are always
unambiguously resolved during parsing.
Depending on a and b, it can be non-commutative even in C.
That's the reason why terms like 'oder of evaluation',
'operator precedence', 'sequence point', 'side-effects' etc. exist.

When is "+" non-commutative in C (ignoring the unary "+" operator)? I
can't think of any cases where a+b and b+a have different meanings.
They might yield different results in some cases due to unspecified or
implementation-defined behavior, but in all such cases there's no
consistent difference between a+b and b+a.
 
M

Markus Becker

Keith Thompson said:
(Missing attribution; I wrote the stuff starting with 'The "+"
operator is usually commutative'.)

Sorry for that.
What happens inside f() and g() obviously affects the result, but it
doesn't affect the meaning of the "+" operator; that's determined by
their declared return types.

You are right, the '+' itself is commutative:

ff = f(x);
gg = g(y);

then ff+gg == gg+ff
No, why would it? That's a unary operator; commutativity is

Right, and '+' in the context of string has nothing to do with
the mathematical definition how to add to numbers and that the
order in which they are added does not matter.

What I wanted to say (and it obviously did not come through to
you) is, that sometimes sub-optimal symbols are used/defined
for their purpose. '+' is associated with 'addition' which is
commutative, '*' is associated with division ...
meaningless for it. The fact that it uses the same symbol as
multiplication is not significant. Unary and binary "*" are always

Sure it is not significant for the purpose, if you and the compiler
know what they are doing. It's just a misleading choice of symbols.
They might yield different results in some cases due to unspecified or
implementation-defined behavior, but in all such cases there's no
consistent difference between a+b and b+a.

OK, in my example there were side effects for which, after some after-
thought the poor innocent '+'-Operator cannot be blamed. It just adds
the two values it gets, if the values are always the same, then the
result is always the same.

I stand corrected.

Markus
 
D

Daniel Rudy

At about the time of 12/31/2005 11:27 AM, pemo stated the following:
main(_){for(--_;putchar(_++["J!Mpwf!Zpv\1"]-1););}


Here it is a little clearer [hopefully?]

#include <stdio.h>

// x will be 1 (the name of this app would be in argv[0]) if we
// don't invoke the app with some args.
//
main(x)
{
char c;

// zero then!
//
--x;

while(c = "J!Mpwf!Zpv\1"[x])
{
// No need for the -1 if we add 1 to the literal's characters...
//
// "I Love You\1"
//
c = c - 1;

x++;

putchar(c);
}
}

You know, the code that the OP provided is the reason why I hate
wannabe's trying to be hack programmers to impress the rest of us.
Anyone who codes like that needs to be shot, not once, not twice, but
thrice. Perferably in the groin.


--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
 
M

Malcolm

Keith Thompson said:
When is "+" non-commutative in C (ignoring the unary "+" operator)? I
can't think of any cases where a+b and b+a have different meanings.
They might yield different results in some cases due to unspecified or
implementation-defined behavior, but in all such cases there's no
consistent difference between a+b and b+a.
It's not associative

a = INT_MAX;
b = 1;
c = -1;

(a + b) + c;
and
a + (b + c);

won't necessarily be the same.
 

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,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top