Pointer Ambiguity

U

Umesh

Please read the comments.
Program to multiply the elements of an array with its size.
#define s 5
#include<stdio.h>

void mul(int *p)
{
for(int i=0;i<s;i++)
{
printf("%d ",*p*s);
p++;
}
}

main()
{
int a,i;
printf("Enter %d No. ",s);
for(i=0;i<s;i++)
scanf("%d",&a);
mul(a);/* it should be mul(&a) why not?*/
return 0;
}
 
K

Keith Thompson

Richard Heathfield said:
Ian Collins said:

What's incorrect about that?

In C90, it's correct (but poor style). In C99, it's illegal. Since
the code uses a declaration in a for loop:

for(int i=0;i<s;i++)

we can infer that it's intended to be C99, and that main is declared
incorrectly. Or that it's intended to be C90, and the for loop is
written incorrectly. Or, more likely, that the compiler is invoking
his compiler in a mode that conforms to neither standard, and doesn't
know or care whether his code is correct.
 
M

Malcolm McLean

blufox said:
Ideally that should be
int main(void)

thanks
Ideally.
But implicit int is conforming, and arguably a good idea, since it demotes
size_t.
An empty argument list means that the function takes no or more parameters.
So the fact that main(void) is allowed is a quirk.
 
K

Keith Thompson

Keith Thompson said:
we can infer that it's intended to be C99, and that main is declared
incorrectly. Or that it's intended to be C90, and the for loop is
written incorrectly. Or, more likely, that the compiler is invoking
his compiler in a mode that conforms to neither standard, and doesn't
know or care whether his code is correct.

Whoop, I meant that the *original poster* is invoking his compiler in
a mode that etc.
 
F

Flash Gordon

Malcolm McLean wrote, On 17/06/07 09:32:
Ideally.
But implicit int is conforming, and arguably a good idea, since it
demotes size_t.

Implicit int has nothing to do with size_t so I really can't see what
you are trying to say.
An empty argument list means that the function takes no or more
parameters. So the fact that main(void) is allowed is a quirk.

It is still a good idea because it is the only way to ensure the
compiler will complain if you then call main recursively passing it
parameters. This is more important for other functions (where it does
not only apply to recursive calls), but it is a good habit.
 
I

Ian Collins

Richard said:
Ian Collins said:


What's incorrect about that?
The fact (as Keith beat me to pointing out) that it was associated with
this:

for(int i=0;i<s;i++)
 
R

Richard Heathfield

Ian Collins said:
The fact (as Keith beat me to pointing out) that it was associated
with this:

for(int i=0;i<s;i++)

Since he uses implicit int, I infer that he's writing in C90, in which
case it's the for loop that is incorrect.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

regis said:
About the order the #define and the #include directives:
what happens if printf() is declared as:

int printf (const char * s, ...);

Won't the declaration be expanded into:

int printf (const char * 5, ...);

Yes, and because of that, <stdio.h> is not allowed to declare printf that
way.
 
R

regis

Umesh said:
Please read the comments.
Program to multiply the elements of an array with its size.
#define s 5
#include<stdio.h>

About the order the #define and the #include directives:
what happens if printf() is declared as:

int printf (const char * s, ...);

Won't the declaration be expanded into:

int printf (const char * 5, ...);
 
R

regis

Harald said:
Yes, and because of that, <stdio.h> is not allowed to declare printf that
way.

so, is the use of double underscore prefixes for identifiers
or the use of no identifier at all
mandatory for standard headers ?
 
H

Harald van =?UTF-8?B?RMSzaw==?=

regis said:
so, is the use of double underscore prefixes for identifiers
or the use of no identifier at all
mandatory for standard headers ?

There are other reserved identifiers that could be used, but yes, standard
headers can't use identifiers for parameter names that user code is allowed
to use.
 
C

Chris Torek

[given something like:

which causes the identifier s to expand to the number 5 if an
unadorned "s" appears inside the contents of <stdio.h>, assuming

so, is the use of double underscore prefixes for identifiers
or the use of no identifier at all
mandatory for standard headers ?

The C standards do not say *how* the implementation has to avoid
the problem, just that it must avoid the problem.

Two obvious and simple methods are, indeed, to use double-underscore
prefixes or omit identifier names, e.g.:

char *strcpy(char *restrict __dst, const char *restrict);

However, an implementor can use *any* reserved-to-the-implementor
name, e.g.:

char *strcpy(char *restrict memset, const char *restrict _E);

(which is admittedly kind of bizarre), or even compiler-specific
extensions such as:

#pragma implementor_namespace_hack
char *strcpy(char *restrict dst, const char *restrict src);
#pragma end_implementor_namespace_hack

or similar. If <stdio.h> or -- as in this case -- <string.h> is
not, in fact, an ordinary file at all -- e.g., if it simply turns
on a flag in the compiler that says that the header has been included
-- there may even be no preprocessing phase involved, hence no
"name collision hazard" in the first place.
 
R

regis

Chris said:
[given something like:

which causes the identifier s to expand to the number 5 if an
unadorned "s" appears inside the contents of <stdio.h>, assuming
that <stdio.h> is an ordinary file that is expanded in the ordinary
way]
[...]

If <stdio.h> or -- as in this case -- <string.h> is
not, in fact, an ordinary file at all -- e.g., if it simply turns
on a flag in the compiler that says that the header has been included
-- there may even be no preprocessing phase involved, hence no
"name collision hazard" in the first place.

Ok. So, along these lines, I guess

#define printf foo
#include <stdlib.h>

also gives unpredictable results, that is, one cannot predict if

int foo (const char *, ...);

or

int printf (const char *, ...);

will be declared.
 
A

Army1987

regis said:
Chris said:
[given something like:
#define s 5
#include<stdio.h>

which causes the identifier s to expand to the number 5 if an
unadorned "s" appears inside the contents of <stdio.h>, assuming
that <stdio.h> is an ordinary file that is expanded in the ordinary
way]
[...]

If <stdio.h> or -- as in this case -- <string.h> is
not, in fact, an ordinary file at all -- e.g., if it simply turns
on a flag in the compiler that says that the header has been included
-- there may even be no preprocessing phase involved, hence no
"name collision hazard" in the first place.

Ok. So, along these lines, I guess

#define printf foo
#include <stdlib.h>

also gives unpredictable results, that is, one cannot predict if

int foo (const char *, ...);

or

int printf (const char *, ...);

will be declared.

From the C99 rationale, 6.10.3:
As with any other powerful language feature, keyword redefinition is subject
to abuse. Users

cannot expect any meaningful behavior to come about from source files
starting with

#define int double

#include <stdio.h>

or similar subversions of common sense.
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top