Thread: RE: [Dev-C++] #DEFINE versus cont variables in array inicializations (Page 2)
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
|
From: Ioannis V. <iv...@te...> - 2003-05-30 23:24:34
|
A small correction: > -----Original Message----- > From: Per Westermark [mailto:pw...@ia...] > Sent: Saturday, May 31, 2003 3:18 AM > To: Ioannis Vranos > Cc: Dev-C++ Mailing List > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array > inicializations > > > Give a declaration: > > const int SIZE = 7; > > If you don't take the address of it, the compiler will generate code > looking like: It is difficult for the compiler to know if I use its address in another file. Usually the linker notices the uses in other files. > > pushl $7 > > If you take the address of it, the compiler will notice and > generate code > like: > > pushl $_SIZE > > ... > > _SIZE: > .long 7 > > where the second case will store _SIZE in .text and not in .data. I can't understand the above very much but I do not think the compiler cn check every file for this, only the linker. Also what if I make obj files and then add some code in a cpp file that uses the address, make a new obj annd then link all objs together? > You will be able to take the address of SIZE from one object > file. If you > declare 'const int SIZE = 7;' in another file to and try to take the > address of it, you will correctly get a linker error. If you > in the other > file declares 'extern const int SIZE', that file will always > reference the > variable SIZE, since it can't do any inlining. => This is a bit difficult. You know, extern const int SIZE=17; is a *definition* in the absense of another definition. Ioannis Vranos * Programming pages: http://www.noicys.freeurl.com * Alternative URL 1: http://run.to/noicys * Alternative URL 2: http://www.noicys.cjb.net |
|
From: Ioannis V. <iv...@te...> - 2003-05-30 19:24:30
|
> -----Original Message----- > From: Per Westermark [mailto:pw...@ia...] > Sent: Saturday, May 31, 2003 1:45 AM > To: Ioannis Vranos > Cc: Dev-C++ Mailing List > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array > inicializations > > > If you try to compare the address of SIZE from two different > modules, you > will - I haven't tested for different compilers - probably > get a linker > error, since both object files will contain a _SIZE symbol. But that would be broken behaviour. So I do not think we will get a linker error. > But then again > - 'a const &int = <value>' is a complicated declaration just to get a > "magic" address to compare against. I do not understand the above. The compiler has to produce an address when we use that address, the same way that inline functons do have an address. Ioannis Vranos * Programming pages: http://www.noicys.freeurl.com * Alternative URL 1: http://run.to/noicys * Alternative URL 2: http://www.noicys.cjb.net |
|
From: <jp...@bo...> - 2003-05-31 04:40:10
|
Does anyone know where I can find information - any website - on=20
reading/writing JPEG files?
Thanks for any help.
Juliano
--=20
Visite minha p=E1gina: http://www.jpavel.kit.net
|
|
From: <or...@vp...> - 2003-05-29 21:10:02
|
Per Westermark wrote: > I guess you don't think of gcc as a decent compiler then. An interesting thing I found, when examining g++ deeply: GCC is so smart, it even optimizes everything possible. Suppose you have a function, that returns a class. The normal behaviour would be: call copy constructor, return copied object. BUT if the variable was a local variable (created in the function) and you return that, then the "theoretical" behaviour would still be: copy object, return copied object, delete local variable, BUT gcc makes it very different: it simply return the local object without any copy, etc. It is not harmful, as the object would have been deleted anyway, so it is truly easier to simply return the local variable one-in-one. It is faster for sure. It truly does this, as I stated - I have checked the pointer for the object, and it is the same in the function, and the after return. Interesting... -- Greetings, Balázs |
|
From: Maxim Y. <ma...@en...> - 2003-05-30 08:09:21
|
Hello, OROSZI!
Friday, May 30, 2003 0:10:34 You wrote to dev...@li...:
OB> Per Westermark wrote:
>> I guess you don't think of gcc as a decent compiler then.
OB> An interesting thing I found, when examining g++ deeply:
OB> GCC is so smart, it even optimizes everything possible.
OB> Suppose you have a function, that returns a class. The normal behaviour
OB> would be: call copy constructor, return copied object.
OB> BUT if the variable was a local variable (created in the function) and
OB> you return that, then the "theoretical" behaviour would still be: copy
OB> object, return copied object, delete local variable, BUT gcc makes it
OB> very different: it simply return the local object without any copy, etc.
OB> It is not harmful, as the object would have been deleted anyway, so it
OB> is truly easier to simply return the local variable one-in-one. It is
OB> faster for sure.
Do GCC really does like this? I mean, even if return value is class, not a
referense? That's terrible then! Because you can run into trouble when the
returned value should be used in another function call:
class C { ... };
C getC(int something){ C c(something); return c; }
void f(C& c1, C& c2);
f(getC(1), getC(2)); <-- one of C objects will override another (because it
can (or "will") be created at the same address).
I agree, this can happed, if getC is declared as returning reference:
C& getC(int something){ C c(something); return c; }
, but that's what I always try to avoid (yes, I have functions like 'f', they
work with std::string objects);
OB> It truly does this, as I stated - I have checked the pointer for the
OB> object, and it is the same in the function, and the after return.
OB> Interesting...
I usually turn off any optimization, 'cos I heard that GCC can "optimize too
much" :-)
--
Regards!
Maxim
|
|
From: <or...@vp...> - 2003-05-30 14:41:18
|
Maxim Yemelyanov wrote:
> Do GCC really does like this? I mean, even if return value is class, not a
> referense?
Yes, that's what I said.
> That's terrible then! Because you can run into trouble when the
> returned value should be used in another function call:
>
> class C { ... };
>
> C getC(int something){ C c(something); return c; }
>
> void f(C& c1, C& c2);
>
> f(getC(1), getC(2)); <-- one of C objects will override another (because it
> can (or "will") be created at the same address).
WHAT?
No, what happens here is, that for getC(1) and getC(2) DIFFERENT objects
will be returned. While would they be the same??? When you call getC(),
then a LOCAL variable will be created. THAT local variable is returned
without copy, as it would be destroyed anyway. So, instead of copying
it, and destroying the local variable (as it gets out of scope at the
end of getC), GCC will simply return c, without copy.
I don't see why this would cause a problem. Even in your example, it
works perfectly.
I don't understand you clearly...
> I agree, this can happed, if getC is declared as returning reference:
>
> C& getC(int something){ C c(something); return c; }
It is wrong. A function should NEVER return a reference to a LOCAL
variable, as the local variable will be destroyed, and an invalid
reference will be returned.
> , but that's what I always try to avoid
That is wise :)
> I usually turn off any optimization, 'cos I heard that GCC can "optimize too
> much" :-)
I almost always use level 4 optimization, but at least level 3. It
didn't cause any trouble for me so far. Even wxWindows is compiled with
-O4 for me, and it works fine.
There is no problem using optimization - it won't do harm (in the 90% of
the cases).
--
Greetings,
Balázs
|
|
From: Per W. <pw...@ia...> - 2003-05-30 15:20:14
|
What smart compilers do, is to let the caller allocate the memory for the
temporary object, and then have the function perform all object
manipulation with the temporary object. On return, there is no need for
any object copying, since the resulting object is in the callers stack
frame and not in the called functions.
If the caller wants to make two calls, the compiler will - depending on
object usage - allocate one or two temporary objects that the called
function will use.
/Per W
On Fri, 30 May 2003, OROSZI Bal=E1zs wrote:
> Maxim Yemelyanov wrote:
> > Do GCC really does like this? I mean, even if return value is class, no=
t a
> > referense?
>
> Yes, that's what I said.
>
> > That's terrible then! Because you can run into trouble when the
> > returned value should be used in another function call:
> >
> > class C { ... };
> >
> > C getC(int something){ C c(something); return c; }
> >
> > void f(C& c1, C& c2);
> >
> > f(getC(1), getC(2)); <-- one of C objects will override another (becaus=
e it
> > can (or "will") be created at the same address).
>
> WHAT?
> No, what happens here is, that for getC(1) and getC(2) DIFFERENT objects
> will be returned. While would they be the same??? When you call getC(),
> then a LOCAL variable will be created. THAT local variable is returned
> without copy, as it would be destroyed anyway. So, instead of copying
> it, and destroying the local variable (as it gets out of scope at the
> end of getC), GCC will simply return c, without copy.
> I don't see why this would cause a problem. Even in your example, it
> works perfectly.
>
> I don't understand you clearly...
>
> > I agree, this can happed, if getC is declared as returning reference:
> >
> > C& getC(int something){ C c(something); return c; }
>
> It is wrong. A function should NEVER return a reference to a LOCAL
> variable, as the local variable will be destroyed, and an invalid
> reference will be returned.
>
> > , but that's what I always try to avoid
>
> That is wise :)
>
> > I usually turn off any optimization, 'cos I heard that GCC can "optimiz=
e too
> > much" :-)
>
> I almost always use level 4 optimization, but at least level 3. It
> didn't cause any trouble for me so far. Even wxWindows is compiled with
> -O4 for me, and it works fine.
> There is no problem using optimization - it won't do harm (in the 90% of
> the cases).
>
> --
> Greetings,
> Bal=E1zs
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: eBay
> Get office equipment for less on eBay!
> http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: <or...@vp...> - 2003-05-31 11:08:35
|
Hello Maxim!
Maxim Yemelyanov wrote:
> Hello, OROSZI!
Balázs :) This is my first name. We just write it the opposite way.
> I just dont know how function stack works. When I call foo(), where its stack
> starts? Just on caller's stack's free space?
>
> Because what I thought was:
> 1) getC(1) creates a local object at address xxxx (on its stack), this object
> will be destroyed at the end of f().
No, it will be destroyed at the end of getC(1). But here is where gcc
optimises. It does not destroy it, instead it simply "returns" it.
> 2) getC(2) creates a local object _at_the_same_ address xxxx.
No, why would it? It is a different call, different local variable. We
would be in BIG trouble if gcc would behave like that...
> 3) Since both objects exist until end of f(), this can cause a trouble.
See above, like that, there is no problem :)
> But when I tried a simple test (added output to getC), I saw that two local
> objects are created at different addresses.
Of course. It is two DIFFERENT function calls. I was talking about the
local variable, and the returned object. Try this:
Store the address of the local variable in getC(x), and then check the
returned object's address too. Like this:
C* local_address;
C* returned_address;
getC(int)
{
C c(1);
local_address = &c;
return c;
}
main()
{
C c;
c = getC(1);
returned_address = &c;
/* Here, local_address and global_address "should" be the same */
/* TRY IT! */
}
> OB> I don't understand you clearly...
> That's because I don't see the whole picture (in all details). Thanks, your
> answer have cleared some areas of the topic to me :-)
> Moreover, since most of time I used pure C, such things as C++ classes and
> references, passed between functions (and optimization of all this stuff) is
> still not enough clear to me.
> That's why I sometimes ask stupid questions. Sorry :-\
Ahh. No problem :) I am not enough familiar with C++ yet either. :)
> What are these 10%? When I should be careful about optimization?
I don't know. I haven't got any trouble with optimization yet. I have
seen LARGE projects, that use -O3 optimisation, and they work fine. So I
think you can safely enable it. GCC is getting better and better, and
GCC 3.2 can be considered modern enough not to f**k up the program.
--
Greetings,
Balázs
|
|
From: <Avi...@ne...> - 2003-05-29 21:50:51
|
Typo I meant 32 bits :-)
Per Westermark <pw...@ia...> wrote:
>You are using mighty big integers :-)
>
>A 32-byte unsigned integer would store numbers up to 1*10^77
>
>/Per W
>
>On Thu, 29 May 2003, Avik Ghose wrote:
>
>> Hi Andre,
>> you are right, there's probably no third way out. Now I prefer to use the first one due to two reasons.
>> 1> Being textual subsitution, the #define macro does not use up memory size whereas an integer uses up 32 bytes, though that is negligent for most purposes.
>> 2> The more important being that apart from compiler systems that support C++ along with C, the interpretation of const by the compilers around is a bit non-standard. Like in the Cygwin gcc complier assigment to const variables result only in a warning at compile time and program runs fine, and prints out 20!!!.
>> #include <stdio.h>
>> int main()
>> {
>> const int i = 10;
>> i=20;
>> printf("%d\n",i);
>> return 0;
>> }/*main*/
>> So well although I cannot remember of a third way to do it right now, obviously the first approach is better.
>>
>>
>>
>>
>> André_Macário_Barros <and...@su...> wrote:
>> Dear Users,
>>
>> For the sake of flexibility, I think we only have two ways to iniciatize
>> a
>> size of an array:
>> 1) via #define:
>> #define MAX 10
>> ...
>> int vect[MAX];
>> ...
>>
>> 2) via cont variable:
>> const int size=10;
>> ...
>> int vetc[size];
>> ...
>>
>> So, in both ways, everytime if I need to change the size of the arrays, it´s
>> only necessary to change 10 to the other value.
>>
>> -->My questions:
>> 1) Is there more ways to to this?
>> 2) For theese two ways presented here, when use one and when use the other?
>> Explaining a little more what I need to know: in a "good programming
>> technique"
>> point of view, what of theese two is the preferred of the programmers
>> (please
>> don´t answer "pointers" ...lol).
>>
>> Regards
>> André
>>
>>
>>
>>
>> -------------------------------------------------------
>> This SF.net email is sponsored by: eBay
>> Get office equipment for less on eBay!
>> http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5
>> _______________________________________________
>> Dev-cpp-users mailing list
>> Dev...@li...
>> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
>> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>>
>>
>> Thanx and Regards
>> Avik Ghose
>> Catch all the cricket action. Download Yahoo! Score tracker
>
>
--
Regards
---------------------------------------
Avik Ghose
Software Engineer (Real Time Group)
Rebaca
Systron Building, 3rd Floor
Plot No: J-5, Block: EP & GP
Saltlake Electronics Complex, Sector V
Kolkata: 700091
India
Phone: 91-33-2357-7177 ext 16
Fax: 91-33-2357-7178
Mobile: 91-0-9830039737
__________________________________________________________________
McAfee VirusScan Online from the Netscape Network.
Comprehensive protection for your entire computer. Get your free trial today!
http://channels.netscape.com/ns/computing/mcafee/index.jsp?promo=393397
Get AOL Instant Messenger 5.1 free of charge. Download Now!
http://aim.aol.com/aimnew/Aim/register.adp?promo=380455
|
|
From: Ioannis V. <iv...@em...> - 2003-05-31 00:22:35
|
> -----Original Message----- > From: Ioannis Vranos [mailto:iv...@em...] > Sent: Saturday, May 31, 2003 3:13 AM > To: Dev-C++ Mailing List (dev...@li...) > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array > inicializations > > > > -----Original Message----- > > From: Per Westermark [mailto:pw...@ia...] > > Sent: Saturday, May 31, 2003 6:38 AM > > To: Ioannis Vranos > > Cc: Dev-C++ Mailing List > > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array > > inicializations > > > > > > See below > > > > > > If you know that you need to take the address in another file, then > > declare it as: > > extern const int SIZE = 7; > > > I am sorry to tell you this, but this is *nonsense*. The C++ > standard doesn't require to define it like this. I just checked it and it seems you are right. Don't know why yet. However does the above style make the compiler to give it an address? That would be very strange. I shall check the standard now. Ioannis Vranos * Programming pages: http://www.noicys.freeurl.com * Alternative URL 1: http://run.to/noicys * Alternative URL 2: http://www.noicys.cjb.net |
|
From: Per W. <pw...@ia...> - 2003-05-31 00:52:49
|
I assume gcc is a bit naughty. However, as long as I know about the problem, it does allow me to write working code that is portable to other compilers. /Per W On Sat, 31 May 2003, Ioannis Vranos wrote: > > -----Original Message----- > > From: Ioannis Vranos [mailto:iv...@em...] > > Sent: Saturday, May 31, 2003 3:13 AM > > To: Dev-C++ Mailing List (dev...@li...) > > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array > > inicializations > > > > > > > -----Original Message----- > > > From: Per Westermark [mailto:pw...@ia...] > > > Sent: Saturday, May 31, 2003 6:38 AM > > > To: Ioannis Vranos > > > Cc: Dev-C++ Mailing List > > > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array > > > inicializations > > > > > > > > > See below > > > > > > > > > If you know that you need to take the address in another file, then > > > declare it as: > > > extern const int SIZE = 7; > > > > > > I am sorry to tell you this, but this is *nonsense*. The C++ > > standard doesn't require to define it like this. > > > > I just checked it and it seems you are right. Don't know why yet. > > > However does the above style make the compiler to give it an address? That > would be very strange. I shall check the standard now. > > > > > Ioannis Vranos > > * Programming pages: http://www.noicys.freeurl.com > * Alternative URL 1: http://run.to/noicys > * Alternative URL 2: http://www.noicys.cjb.net > > > > > ------------------------------------------------------- > This SF.net email is sponsored by: eBay > Get office equipment for less on eBay! > http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5 > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > |
|
From: Ioannis V. <iv...@em...> - 2003-05-31 01:19:11
|
> -----Original Message-----
> From: dev...@li...
> [mailto:dev...@li...] On Behalf
> Of Ioannis Vranos
> Sent: Saturday, May 31, 2003 3:22 AM
> To: Dev-C++ Mailing List
> Subject: RE: [Dev-C++] #DEFINE versus cont variables in array
> inicializations
>
>
> I just checked it and it seems you are right. Don't know why yet.
>
>
> However does the above style make the compiler to give it an
> address? That
> would be very strange. I shall check the standard now.
TC++PL on pages 199,200 says that const has by default internal linkage. So
the definition must be accomanied by the keyword extern too.
So my code becomes:
temp2.cpp:
extern const int x=17;
temp.cpp:
#include <iostream>
extern const int x;
int main()
{
const unsigned char *p=reinterpret_cast<const unsigned char *>(&x);
// Shows x representation in memory in byte values
// including padding bits
for(unsigned long i=0; i<sizeof(x); ++i)
std::cout<<static_cast<short>(p[i])<<" ";
}
C:\c>g++ temp.cpp temp2.cpp -o temp
C:\c>temp
17 0 0 0
C:\c>
So in this case the compiler can know if the const object or *reference* is
accessed in another translation unit.
However why a compiler would "inline" const int x=7; and would not be able
to "inline" const int &x=7; isn't clear and would be nice if you explained
it to us. And please do not involve L1/L2 caches, we are talking about
inline substitution here. And my CPU may have no cache.
Ioannis Vranos
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net
|
|
From: Per W. <pw...@ia...> - 2003-05-31 12:17:59
|
I don't know why gcc doesn't optimize a 'const int &var = <value>' when
referenced. The only thing I could guess is that they never thought
it useful to optimize the use of the above declaration, since the
most common use for a const reference is something like:
int var = 12;
void func(const int& ref) {
// do something
}
int main() {
func(var);
}
In this case, the compiler doesn't know that func() is only called with
var as parameter, i.e. with a constant value, so it can't optimize.
If you think about it, what extra results are you expecting from the
following declaration? It is basically an unchangeable pointer to an
unchangeable value. But what improvements should it give to your program?
const int &var = 12;
/Per W
On Sat, 31 May 2003, Ioannis Vranos wrote:
> > -----Original Message-----
> > From: dev...@li...
> > [mailto:dev...@li...] On Behalf
> > Of Ioannis Vranos
> > Sent: Saturday, May 31, 2003 3:22 AM
> > To: Dev-C++ Mailing List
> > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array
> > inicializations
> >
> >
> > I just checked it and it seems you are right. Don't know why yet.
> >
> >
> > However does the above style make the compiler to give it an
> > address? That
> > would be very strange. I shall check the standard now.
>
>
> TC++PL on pages 199,200 says that const has by default internal linkage. So
> the definition must be accomanied by the keyword extern too.
>
>
> So my code becomes:
>
>
> temp2.cpp:
>
> extern const int x=17;
>
>
> temp.cpp:
>
> #include <iostream>
>
>
> extern const int x;
>
>
> int main()
> {
> const unsigned char *p=reinterpret_cast<const unsigned char *>(&x);
>
>
> // Shows x representation in memory in byte values
> // including padding bits
> for(unsigned long i=0; i<sizeof(x); ++i)
> std::cout<<static_cast<short>(p[i])<<" ";
>
>
> }
>
>
> C:\c>g++ temp.cpp temp2.cpp -o temp
>
> C:\c>temp
> 17 0 0 0
> C:\c>
>
>
> So in this case the compiler can know if the const object or *reference* is
> accessed in another translation unit.
>
>
>
> However why a compiler would "inline" const int x=7; and would not be able
> to "inline" const int &x=7; isn't clear and would be nice if you explained
> it to us. And please do not involve L1/L2 caches, we are talking about
> inline substitution here. And my CPU may have no cache.
>
>
>
>
> Ioannis Vranos
>
> * Programming pages: http://www.noicys.freeurl.com
> * Alternative URL 1: http://run.to/noicys
> * Alternative URL 2: http://www.noicys.cjb.net
>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: eBay
> Get office equipment for less on eBay!
> http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Ioannis V. <iv...@em...> - 2003-05-31 22:33:17
|
> -----Original Message-----
> From: Per Westermark [mailto:pw...@ia...]=20
> Sent: Saturday, May 31, 2003 6:52 PM
> To: Ioannis Vranos
> Cc: 'Dev-C++ Mailing List'
> Subject: RE: [Dev-C++] #DEFINE versus cont variables in array=20
> inicializations
>=20
>=20
> I don't know why gcc doesn't optimize a 'const int &var =3D=20
> <value>' when
> referenced.
I was speaking compiler indepedently. You had said that const references
occupy space while only const variables can be "inlined", and then you
confused me with maps, data files and L1/L@ caches. :) I do not care =
what
the current version of GCC does on this matter, the next version may =
behave
differently or the previous versions or even ports of the same version =
on
different machines.
For built in array sizes only const variables and #define can do the =
job. In
general when I want to define a constant I use a const variable, but if =
I
were space concerned I would use a const reference since references do =
not
have an address and in theory are more easy to be optimised out than =
objects
(the same thing that happens when we pass const references to functions
instead of object copies).
> The only thing I could guess is that they never thought
> it useful to optimize the use of the above declaration, since the
> most common use for a const reference is something like:
>=20
> int var =3D 12;
>=20
> void func(const int& ref) {
> // do something
> }
>=20
> int main() {
> func(var);
> }
>=20
> In this case, the compiler doesn't know that func() is only=20
> called with
> var as parameter, i.e. with a constant value, so it can't optimize.
Yes, but var is "inlined". On the other hand calling func(7), a =
temporary is
created.
> If you think about it, what extra results are you expecting from the
> following declaration? It is basically an unchangeable pointer to an
> unchangeable value. But what improvements should it give to=20
> your program?
>=20
> const int &var =3D 12;
I consider that the compiler could more easily inline it than const int
var=3D12; But anyway in real world programs for PCs, whether it will =
inline it
or not, it doesn't matter.
I disagree(d) with you that a const variable can be inlined while a =
const
reference cannot. Theoretically both can be inlined, system-indepedently
speaking.
Ioannis Vranos
=20
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net
|
|
From: Per W. <pw...@ia...> - 2003-05-31 23:24:48
|
You do realise that a reference is just a slightly modified pointer, with
required initialization and without any pointer manipulation allowed.
While you could do:
const int &ref =3D 7;
the majority of code using references does:
int var =3D 7;
const int &ref =3D var;
Since 'const int &ref' allows for aliasing, i.e. that you have other
access methods to change the value that the reference points to, it is
hard - and often impossible - for the compiler to consider optimization
from a reference.
Since a reference - like a pointer - is an indirect access method, they
are not optimal for object access, unless you do a lot of localized
accesses using the same reference, in which case the compiler may cache
the reference in a register and thereby getting the same access times as
for a variable with a fixed address. Pointers and references are
at their best when you have a large object that you don't want to send as
a value, i.e. instead of a function taking a large struct as parameter, it
can take a reference to that struct.
However, that reference is - internally to the machine - identical to a
pointer, and when the compiler tries to access anything through the
reference, it have to do an indirection.
A reference isn't sometihng of zero size that doesn't exist. Except for
rare cases when the compiler is 100% sure about what it points to, the
reference have the same size - and will generate identical code - as a
pointer.
The whole id=E9a with a pointer or a reference is to either allow a variabl=
e
to point at different entities of something (such as when a constructor or
function takes a reference without knowing at compile time what it will be
initialized to) or when you have an object too large to send as a
parameter.
In both these cases, it is impossible for the compiler to optimize away
the address value stored by the reference, since that would either make
the constructor or function only supporting a hardcoded parameter, or
would in the second case force the large object to be sent on the stack
instead of just the address of the object.
So:
const int &ref =3D 7;
would normally consume (sizeof(void*) + sizeof(int))
Don't know about writing of about data files. I think I mentioned map
files for looking at sizes of generated functions. But then again, the
size of the emitted code has very little correlation with the execution
speed.
About inlining - such as you get with
#define MAX 7
or
const int MAX =3D 7;
- are of course an advantage.
If the compiler generates code
movl $7,%edx
instead of
movl _MAX,%edx
there is no need for an extra memory reference, since in the first
alternative, the op-code already contained the value 7, while in the
second alternative, the processor must first parse the op-code, then check
it's data cache and/or issue a data read, and finally perform the move,
i.e. assigning a value to the eax 32-bit register.
/Per W
On Sun, 1 Jun 2003, Ioannis Vranos wrote:
> > -----Original Message-----
> > From: Per Westermark [mailto:pw...@ia...]
> > Sent: Saturday, May 31, 2003 6:52 PM
> > To: Ioannis Vranos
> > Cc: 'Dev-C++ Mailing List'
> > Subject: RE: [Dev-C++] #DEFINE versus cont variables in array
> > inicializations
> >
> >
> > I don't know why gcc doesn't optimize a 'const int &var =3D
> > <value>' when
> > referenced.
>
>
> I was speaking compiler indepedently. You had said that const references
> occupy space while only const variables can be "inlined", and then you
> confused me with maps, data files and L1/L@ caches. :) I do not care what
> the current version of GCC does on this matter, the next version may beha=
ve
> differently or the previous versions or even ports of the same version on
> different machines.
>
> For built in array sizes only const variables and #define can do the job.=
In
> general when I want to define a constant I use a const variable, but if I
> were space concerned I would use a const reference since references do no=
t
> have an address and in theory are more easy to be optimised out than obje=
cts
> (the same thing that happens when we pass const references to functions
> instead of object copies).
>
>
>
>
> > The only thing I could guess is that they never thought
> > it useful to optimize the use of the above declaration, since the
> > most common use for a const reference is something like:
> >
> > int var =3D 12;
> >
> > void func(const int& ref) {
> > // do something
> > }
> >
> > int main() {
> > func(var);
> > }
> >
> > In this case, the compiler doesn't know that func() is only
> > called with
> > var as parameter, i.e. with a constant value, so it can't optimize.
>
>
> Yes, but var is "inlined". On the other hand calling func(7), a temporary=
is
> created.
>
>
>
> > If you think about it, what extra results are you expecting from the
> > following declaration? It is basically an unchangeable pointer to an
> > unchangeable value. But what improvements should it give to
> > your program?
> >
> > const int &var =3D 12;
>
>
> I consider that the compiler could more easily inline it than const int
> var=3D12; But anyway in real world programs for PCs, whether it will inli=
ne it
> or not, it doesn't matter.
>
> I disagree(d) with you that a const variable can be inlined while a const
> reference cannot. Theoretically both can be inlined, system-indepedently
> speaking.
>
>
>
>
>
> Ioannis Vranos
>
> * Programming pages: http://www.noicys.freeurl.com
> * Alternative URL 1: http://run.to/noicys
> * Alternative URL 2: http://www.noicys.cjb.net
>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: eBay
> Get office equipment for less on eBay!
> http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
>
|
|
From: Ioannis V. <iv...@em...> - 2003-06-01 01:08:41
|
> -----Original Message-----
> From: Per Westermark [mailto:pw...@ia...]=20
> Sent: Sunday, June 01, 2003 2:24 AM
> To: Ioannis Vranos
> Cc: Dev-C++ Mailing List
> Subject: RE: [Dev-C++] #DEFINE versus cont variables in array=20
> inicializations
>=20
>=20
> You do realise that a reference is just a slightly modified=20
> pointer, with
> required initialization and without any pointer manipulation allowed.
Yes.
=20
> While you could do:
> const int &ref =3D 7;
> the majority of code using references does:
> int var =3D 7;
> const int &ref =3D var;
Not only. Consider the numerous functions and methods getting const T &. =
If
you mean by functionality, then yes.
=20
> Since 'const int &ref' allows for aliasing, i.e. that you have other
> access methods to change the value that the reference points to, it is
> hard - and often impossible - for the compiler to consider=20
> optimization
> from a reference.
No. Consider A string literal like "string". It has an address (behaves =
as a
const char * const array), but it can be optimised away.
=20
> Since a reference - like a pointer - is an indirect access=20
> method, they
> are not optimal for object access, unless you do a lot of localized
> accesses using the same reference, in which case the compiler=20
> may cache
> the reference in a register and thereby getting the same=20
> access times as
> for a variable with a fixed address.=20
When talking about optimizations let's not mention possible run-time
optimisations, only compile time optimisations. Not to mention the fact =
that
registers are controlled by the OS in a non-dedicated system.
In any case we are talking about compiler (compile time) optimisations =
and
in particular about inlining.
> Pointers and references are
> at their best when you have a large object that you don't=20
> want to send as
> a value, i.e. instead of a function taking a large struct as=20
> parameter, it
> can take a reference to that struct.
Yes.
> However, that reference is - internally to the machine -=20
> identical to a
> pointer, and when the compiler tries to access anything through the
> reference, it have to do an indirection.
Yes and no. It depends on what the compiler produces (and in our =
discussion
what the compiler can do in theory).
> A reference isn't sometihng of zero size that doesn't exist.=20
References do not have an address because they were invented exactly so =
as
in many cases to not occupy space by themselves.
> Except for
> rare cases when the compiler is 100% sure about what it points to, the
> reference have the same size - and will generate identical code - as a
> pointer.
In many cases yes. But the rest are not rare cases. Example:
template <class T>
void something(const T &x)
{
// ...
}
something("literal");
The literal would be easy to be inlined.
=20
> The whole id=E9a with a pointer or a reference is to either=20
> allow a variable
> to point at different entities of something (such as when a=20
> constructor or
> function takes a reference without knowing at compile time=20
> what it will be
> initialized to) or when you have an object too large to send as a
> parameter.
Yes.
> In both these cases, it is impossible for the compiler to=20
> optimize away
> the address value stored by the reference, since that would=20
> either make
> the constructor or function only supporting a hardcoded parameter,
In the first case yes.
> or
> would in the second case force the large object to be sent on=20
> the stack
> instead of just the address of the object.
No. Why?
class whatever
{
int x;
public:
whatever(int y):x(y) {}
=20
operator int() const { return x; }
// ...
};
template <class T>
inline const T &something(const T &x)
{
return x+1;
}
int x;
whatever v(7);
x=3Dsomething(v);
In the above case the compiler can optimise out the passing of whatever =
to
something().
=20
> So:
> const int &ref =3D 7;
> would normally consume (sizeof(void*) + sizeof(int))
Something similar to sizeof(int *) + sizeof(int), if it creates a =
temporary
(which will have lifetime till the end of the scope). But nothing =
prohibits
it to inline it as it can also inline a const int var=3D7; I am not =
talking
what the current version of MINGW does here.
The bottom line is do you agree that a compiler can inline a const =
reference
as it can inline a const variable? If you agree it's ok, if you do not
agree, we cannot agree. :)
Ioannis Vranos
=20
* Programming pages: http://www.noicys.freeurl.com
* Alternative URL 1: http://run.to/noicys
* Alternative URL 2: http://www.noicys.cjb.net
|