solution C Puzzle 5 To 7


solution C Puzzle #5
Output:
12
f(1,2)
Reason:
the # operator stringizes its operand, i.e. it puts double quotes
around it.
The ## operator 'glues' its operands together.

The preprocessor expands macro definitions in the text.
It keeps expanding macros as long as it finds any; to block
recursion 
it won't expand a macro that is being expanded already.
in the first printf(), firstly, it is replacing h(f(1,2)) by
g(f(1,2)), and then immediately in the same pass, it calculated
its argument i.e. f(1,2), resulting in "12". Thus getting g("12")
in place of h(f(1,2)). This g("12") results in a string "12".

In short, in first printf()
h(f(1,2)) >> g("12") >> "12"

In the second printf(),
g(f(1,2)) >> "f(1,2)"

solution C Puzzle #6
Reason: "defa1ut:", althought different from "default:", is a valid label. I
  would expect a warning about "unreachable code", but no syntax error.

Answer by gowri kumar sir:
Hi all,
The original description to the question  is this:
If you expect the output of the above program to be *NONE*, I would request
you to check it out!!
As provided in the description, nothing is printed by the program.
There are multiple twists/concepts being tested in the program.
a is declared as integer, with a value of 10.
Switch is based on a, but the case values are character cosntants '1' and
'2'.
For the comparision to happen, the character constant values of '1' and '2'
would be converted to integer. In ASCII, they are 49 and 50 respectively.
Not too sure how many have you recognized it.

Next, the label of default. It is misspelt as defa1ut.
Correcting it as defau1t, doesn't still get the answer none. Because the
character 1 (one) is used instead of l(ell).
On many *nix systems and in many fonts the diference is not visible
immedietly.

Hence the next correction to made is defau1t to default. When it is done,
then NONE is printed.

But then when default is missplet, how did the program compile. Because, you
can have labels in C and pretty much almost anywhere in a function. A label
is defined as a word followed by colon. Hence here defa1ut is taken as a
label.
you can try modifying the program to goto defa1ut and see the behaviour for
yourselves.

Regards,
Gowri Kumar

solution C Puzzle #7
Reason:
The missing "#include <stdlib.h>" is exactly the problem.

In the absence of a visible prototype for malloc(), the compiler
assumes that it returns int. Since int is 32 bits, but the actual
void* value that malloc() *tries* to return is 64 bits, the result is
undefined behavior. In this case, the undefined behavior manifests
itself as returning the low-order (I think) 32 bits of the pointer
value. Since the high-order bits include non-zero values, this loses
information. Casting to int* masks the error, and generates an
invalid pointer value (whose upper half happens to be all-bits-zero).
Dereferencing the pointer value on the next line causes more undefined
behavior, which manifests itself as a seg fault.

It happens to work on IA-32 (more commonly known as x86) because int
and pointer types are both 32 bits. The phrase "happens to work"
means that the undefined behavior manifests itself as the program
doing what you expected it to do. (This is actually worse than what
happens on the IA-64, since it masks the error.)


Reason by my friend1:
According to the C standard, malloc() always returns a suitably aligned address. It is essential because the address (of type void *) can to be further converted to other other types (e.g. int *).


Reason by my friend2:

void* will implicitly cast to any pointer type, provided the compiler knows you have a void* to begin with; if you do not #include <stdlib.h>, then the compiler has no idea that a void* is involved (since it will assume an implicit int return). Presumably a pointer is different sizes on a 32-bit machine and a 64-bit machine, hence the "not always working" aspect of your code.

No comments:

Post a Comment