Strange - a simple assignment statement shows error in VC++ but worksin gcc !

K

karthikbalaguru

Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Which is the correct behaviour ?

The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

Any ideas ?

Thx in advans,
Karthik Balaguru
 
C

Chris Ahlstrom

After takin' a swig o' grog, karthikbalaguru belched out
this bit o' wisdom:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={1,2,3,4,};
int *aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Dude, it's working fine in both of them. It's just that
gcc is being less strict about you treating a 2x2 matrix like a
linear array.

Is that a C file or a C++ file? That might make a difference in
strictness.

Use the Cast, Luke.

--
Let the worthy citizens of Chicago get their liquor the best way
they can. I'm sick of the job. It's a thankless one and full of grief.
-- Al Capone
Let the worthy citizens of the US get their operating system the best way
they can. I'm sick of the job. It's a thankless one and full of grief.
-- Bill Gates
 
J

James Kuyper

karthikbalaguru said:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

I'll assume that there's a missing line which says:

#include <stdio.h>

if there's no such line, you've got even more problems than the one
you're complaining about.
int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

That is correct; in this context the array's name 'a' decays into a
pointer to it's first element. It's first element is a[0], so the
pointer has the type int(*)[2], which is not compatible with int*.
But, in gcc i get the correct output along with

This code violates a constraint. An implementation is required to
produce a diagnostic message when a constraint is violated, but it is
then allowed to accept the program, if it wants to. However, if it
chooses to do so, the behavior is generally undefined. That means that
there's no such thing "the correct output" - all outputs are correct;
failing to produce any output would also be correct. There is, in fact,
no such thing as "incorrect behavior" for such code.
the below warning :-
warning: assignment from incompatible pointer type

Yes, int(*)[2] is incompatible with int*.
In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Which is the correct behaviour ?

The only requirement that applies to your program is the one that says a
diagnostic message should be produced. Since both compilers produced
such a message, both are correct.
The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

Any ideas ?

Yes:
aptr = a[0];


a[0] decays to an int*, the same type as aptr.
 
B

Ben Bacarisse

[I've trimmed the groups -- I can't see any advocacy issues here -- but
in fact it is a plain C question so I have set followups.]

karthikbalaguru said:
For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

That depends on what you mean by working fine.
Which is the correct behaviour ?

The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

The C standard requires a diagnostic and both compilers comply.
VC++'s message is maybe a bit misleading and gcc's is maybe a bit
terse, but all that is required is that the constraint violation be
diagnosed.
Any ideas ?

aptr = &a[0][0];

describes what you are doing more accurately and does not violate any
constraints. There are subtle questions about what you can do with
aptr after this, but these have been done to death in other recent
threads.
 
A

Alex Blekhman

karthikbalaguru said:
For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

It is because you compile it as C with gcc and as C++ with VC++.
The C++ language is more strict about types than C. If you want to
compile the code as C with VC++, then change the file extension to
..C (instead of .CPP). Then VC++ with compile it without any
problem with similar warning about the assignment.

HTH
Alex
 
R

Rainer Weikusat

Alex Blekhman said:
It is because you compile it as C with gcc and as C++ with VC++.
The C++ language is more strict about types than C.

Not in this particular case: The C language definition demands
(6.5.4|3) that converting from int ** (or int *[]) to int * is done by
explicit casting.
 
A

Alex Blekhman

Rainer Weikusat said:
Not in this particular case: The C language definition demands
(6.5.4|3) that converting from int ** (or int *[]) to int * is
done by explicit casting.

Apparently both compilers relax this requirement and accept the
code, though with warning. Probably compiling in ANSI
compatibility mode will produce an error.

Alex
 
K

Keith Thompson

Alex Blekhman said:
Rainer Weikusat said:
Not in this particular case: The C language definition demands
(6.5.4|3) that converting from int ** (or int *[]) to int * is
done by explicit casting.

Apparently both compilers relax this requirement and accept the
code, though with warning. Probably compiling in ANSI
compatibility mode will produce an error.

No, the only requirement is that the compiler must produce a
diagnostic. Once that diagnostic has been produced, the compiler is
free either to reject the translation unit or to continue translating
it; in the latter case, the behavior of the program is not defined by
the standard. There is no relaxation of the requirement, just
different ways of conforming to it.

Followups to comp.lang.c.
 
P

Peter Nilsson

Rainer Weikusat said:
Alex Blekhman said:
It is because you compile it as C with gcc and as C++
with VC++. The C++ language is more strict about types
than C.

Not in this particular case: The C language definition
demands (6.5.4|3) that converting from int ** (or int *[])
to int * is done by explicit casting.

But the language definition doesn't guarantee that conversion
is meaningful beyond allowing conversion back to the original
type and comparing equal. In other words, given...

int a[2][2];
int *aptr = (int *) a;

....there is no strict guarantee that aptr will compare equal
to &a[0][0]. Of course, you're highly unlikely to find an
implementation where that isn't the case, but if you want to
produce &a[0][0], then &a[0][0] (and equivalents) is the best
way of doing that!

That said, even if the conversion does yield the correct
address, there is no further guarantee that aptr[2] can be
dereferenced, or that aptr[3] can be computed. [cf 6.5.6p8]
 
B

Ben Voigt [C++ MVP]

blargg said:
karthikbalaguru wrote: [...]
For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={1,2,3,4,};
int *aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}
[...]
Dude, it's working fine in both of them. It's just that
gcc is being less strict about you treating a 2x2 matrix like a
linear array.

If giving a warning/error is your idea of working fine, what would it take
for you to consider it not working?

Failing to output the diagnostic required by the C++ standard?

Oh, you meant whether the code works, not whether the compiler works? Well
the code doesn't work when compiled with VC++ because the code is wrong.
 
T

The Lost Packet

karthikbalaguru said:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Which is the correct behaviour ?

The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

Any ideas ?

Thx in advans,
Karthik Balaguru

it's down to your compilers - VC++ is a proprietery compiler for C++
from Microsoft, which apart from its own obfuscations is far more strict
than vanilla C compilers such as gcc so unless your code is /perfect/ it
/will/ throw errors. gcc is more forgiving of untidy code, hence you
will get generally more functional results using it wihtout having to
drastically rewrite your source.

--
Disclaimer: No fluffy warm creatures were maimed, dismembered, tortured,
deplumed, discarded, deflowered, dropped, twisted, wrungOut, extended,
respliced, broken, humiliated, irradiated, browbeaten, pickled, deluded,
duped, detained, mishandled, desiccated, bronzed, belittled, coddled,
expelled, deported, imbibed, elected, marginalized, placated,
misrepresented, overworked, underpaid, underappreciated, prepackaged,
overly petted, genetically altered or cloned during the making of this
product, except of course for Bunny and Bear

- IE4 Easter Egg
 
J

Joe Pfeiffer

karthikbalaguru said:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

It doesn't work fine in gcc. gcc is telling you that your code is
wrong, but it's making a guess as to what you meant, and lucky you,
its guess matches what you wanted to happen.
Which is the correct behaviour ?

To respond to either the warning or the error and fix your code.
First, to have your initialization match the declaration, and second
to not write deliberately obfuscating assignments and pointer
dereferences.
The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

They're both telling you that you aren't -- what do you really care
beyond that?
Any ideas ?

Already stated.
 
F

Flash Gordon

The said:
karthikbalaguru said:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Which is the correct behaviour ?

The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

Any ideas ?

Thx in advans,
Karthik Balaguru

it's down to your compilers - VC++ is a proprietery compiler for C++
from Microsoft,

It is *also* a C compiler.
which apart from its own obfuscations is far more strict
than vanilla C compilers such as gcc

gcc is also a C++ compiler and a compiler for various other languages
(gcc standard for GNU Compiler *Collection*).

Also, by default, neither VC++ nor gcc is particularly strict, they both
have extensions enabled. Both, on the other hand, can be made strict by
using the correct options.
so unless your code is /perfect/ it
/will/ throw errors.

Wrong. Both will accept imperfect code without complaint, especially
with the default options. Both when told to conform to the C standard
will only produce warnings, not errors, for some violations (this is
perfectly acceptable in terms of conformance), it's just that they have
chosen different things to be warnings rather than errors.
gcc is more forgiving of untidy code, hence you
will get generally more functional results using it wihtout having to
drastically rewrite your source.

In this case gcc produced a warning because the code is broken. The
correct response to this is to fix the code rather than leaving it
broken in a way which happens to work with one specific version of gcc
but might produce an error or different behaviour with the next version.
 
G

Guest

Use the Cast, Luke.

Abuse of casting leads to abuse of the type system
leads to sloppy programming leads to
unreliably, even undefined, behaviour.
And that is the path to the dark side....
Richard Bos/John Hascall (clc)
 
G

Guest

On 20 Feb, 04:51, The Lost Packet <[email protected]>
wrote:


it's down to your compilers - VC++ is a proprietery compiler for C++
from Microsoft,

nope. It's both a C compiler and a C++ compiler. That it is produced
by a commercial entity is irrelevent.
which apart from its own obfuscations

what obfuscations?
is far more strict than vanilla C compilers such as gcc

this is just rubbish. GCC is *also* both a C compiler and a C++
compiler. In my experience there is little to choose between them
in terms of diagnostics. I even have the impression GCC is slightly
stricter.
so unless your code is /perfect/ it /will/ throw errors.
nonsense.

gcc is more forgiving of untidy code,

please give examples
hence you
will get generally more functional results using it wihtout having to
drastically rewrite your source.

prove it.

<snip>

but actually facts on the other hand...

--
Nick keighley

Dan Pop: "When was the last time you've implemented a real life
application as a strictly conforming program?"
Richard Heathfield: "About 20 minutes ago. It was a new, heavily
optimised pig-launching routine, which gets us a 70% range increase
on previous porcine aeronautic programs."
 
B

Boon

karthikbalaguru said:
Though I get a warning in gcc, [the program] works fine.

Please try a different command line.
$ gcc -std=c89 -pedantic -Wall -Wextra -Werror -O2 file.c
 
E

Ezekiel

The Lost Packet said:
karthikbalaguru said:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Which is the correct behaviour ?

The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

Any ideas ?

Thx in advans,
Karthik Balaguru

it's down to your compilers - VC++ is a proprietery compiler for C++ from
Microsoft, which apart from its own obfuscations is far more strict than
vanilla C compilers such as gcc so unless your code is /perfect/ it
/will/ throw errors. gcc is more forgiving of untidy code, hence you will
get generally more functional results using it wihtout having to
drastically rewrite your source.

--
Disclaimer: No fluffy warm creatures were maimed, dismembered, tortured,
deplumed, discarded, deflowered, dropped, twisted, wrungOut, extended,
respliced, broken, humiliated, irradiated, browbeaten, pickled, deluded,
duped, detained, mishandled, desiccated, bronzed, belittled, coddled,
expelled, deported, imbibed, elected, marginalized, placated,
misrepresented, overworked, underpaid, underappreciated, prepackaged,
overly petted, genetically altered or cloned during the making of this
product, except of course for Bunny and Bear

You are completely clueless. Instead of talking about something which you
obviously know nothing about why don't you stick to your LIES about how
your cluster needs sub-millisecond time synchronization.
 
R

Rainer Weikusat

Peter Nilsson said:
Rainer Weikusat said:
Alex Blekhman said:
:
For the below code, though i get warning in gcc,
it works fine. But, in VC++ compiler, it is showing
compile-time error .

It is because you compile it as C with gcc and as C++
with VC++. The C++ language is more strict about types
than C.

Not in this particular case: The C language definition
demands (6.5.4|3) that converting from int ** (or int *[])
to int * is done by explicit casting.

But the language definition doesn't guarantee that conversion
is meaningful beyond allowing conversion back to the original
type and comparing equal.

I didn't write anything about using such a converted pointer.
 
T

The Lost Packet

Ezekiel said:
The Lost Packet said:
karthikbalaguru said:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Which is the correct behaviour ?

The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

Any ideas ?

Thx in advans,
Karthik Balaguru
it's down to your compilers - VC++ is a proprietery compiler for C++ from
Microsoft, which apart from its own obfuscations is far more strict than
vanilla C compilers such as gcc so unless your code is /perfect/ it
/will/ throw errors. gcc is more forgiving of untidy code, hence you will
get generally more functional results using it wihtout having to
drastically rewrite your source.

--
Disclaimer: No fluffy warm creatures were maimed, dismembered, tortured,
deplumed, discarded, deflowered, dropped, twisted, wrungOut, extended,
respliced, broken, humiliated, irradiated, browbeaten, pickled, deluded,
duped, detained, mishandled, desiccated, bronzed, belittled, coddled,
expelled, deported, imbibed, elected, marginalized, placated,
misrepresented, overworked, underpaid, underappreciated, prepackaged,
overly petted, genetically altered or cloned during the making of this
product, except of course for Bunny and Bear

You are completely clueless. Instead of talking about something which you
obviously know nothing about why don't you stick to your LIES about how
your cluster needs sub-millisecond time synchronization.

**** off, dork.

--
Disclaimer: No fluffy warm creatures were maimed, dismembered, tortured,
deplumed, discarded, deflowered, dropped, twisted, wrungOut, extended,
respliced, broken, humiliated, irradiated, browbeaten, pickled, deluded,
duped, detained, mishandled, desiccated, bronzed, belittled, coddled,
expelled, deported, imbibed, elected, marginalized, placated,
misrepresented, overworked, underpaid, underappreciated, prepackaged,
overly petted, genetically altered or cloned during the making of this
product, except of course for Bunny and Bear

- IE4 Easter Egg
 
E

Ezekiel

The Lost Packet said:
Ezekiel said:
The Lost Packet said:
karthikbalaguru wrote:
Hi,

For the below code, though i get warning in gcc, it works fine.
But, in VC++ compiler, it is showing compile-time error .

int main(void)
{
int a[2][2]={
1,2,
3,4,
};
int *aptr;
aptr=a;
printf("output is %d",*(aptr+1));
return 0;
}

I get the below error in VC++ environment :-
error C2440: '=' : cannot convert from 'int [2][2]' to 'int *'

But, in gcc i get the correct output along with
the below warning :-
warning: assignment from incompatible pointer type

In gcc, i get the correct output as below -
output is 2

Why does the assignment in the above code fail in
VC++ but works fine in the gcc ?

Which is the correct behaviour ?

The above code raises many other queries in my mind -
I wonder if gcc is meeting the C standard or VC++ ?

Any ideas ?

Thx in advans,
Karthik Balaguru
it's down to your compilers - VC++ is a proprietery compiler for C++
from Microsoft, which apart from its own obfuscations is far more
strict than vanilla C compilers such as gcc so unless your code is
/perfect/ it /will/ throw errors. gcc is more forgiving of untidy code,
hence you will get generally more functional results using it wihtout
having to drastically rewrite your source.

You are completely clueless. Instead of talking about something which
you obviously know nothing about why don't you stick to your LIES about
how your cluster needs sub-millisecond time synchronization.

**** off, dork.

Don't cry... sometimes the truth hurts. Nobody believed your nonsense
about sub-millisecond cluster time synchronization and nobody believes your
baloney about compilers.
 

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
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top