|
I'm sorry, but that is a false statement. Look at this code:
struct SomeStruct { ... };
SomeStruct& func() {
SomeStruct s;
return s;
}
void func2(SomeStruct& s) {
s.DoTheFunkyStuff();
}
func2(func());
So, just because it's a reference doesn't guarantee its validity.
I feel that references are in the C++ language because it's syntactic sugar. I have no proof of this being the case, but I just can't find any other reasonable explanation for it.
--
Only in a world this sh*tty could you even try to say these were innocent people and keep a straight face.
|
|
|
|
|
Returning a reference to a object declared on the stack in a function is wrong and bad coding! and will generate a very basic compiler warning ( level 1 ):
It's only a warning because ( I think ) references are implemented as pointers.
from MSDN :
Compiler Warning (level 1) C4172
returning address of local variable or temporary
A function returns the address of a local variable or temporary object. Local variables and temporary objects are destroyed when a function returns, so the address returned is not valid.
Redesign the function so that it does not return the address of a local object.
Max.
|
|
|
|
|
Yes, and so is using a pointer to a previously deleted object.
It is bad yes, but it is still possible. Thus you can't rely on references being always correct.
I know my example was trivial and is obviously erroneous, but I'm still right
--
There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees.
We call it master and servant.
|
|
|
|
|
Or what about this one?
class SomeClass {
RefClass& ref;
public:
SomeClass(RefClass& ref_) : ref(ref_) { ... }
};
.... somewhere in 10<sup>6</sup> lines of code ....
RefClass* pRef = new RefClass();
SomeClass* pObj = new SomeClass(*pRef);
.... somewhere else among those 10<sup>6</sup> lines of code ....
delete pRef;
See what I mean? SomeClass::ref isn't valid. Yes it's a bug, but you can't say that ref is valid after the delete pRef. Same thing goes for pointers to object. Just because a pointer is not NULL doesn't make it valid. That's a dangling pointer, and as you can see, there are also dangling references. In both cases you have a bug on your hands, but it still doesn't make your previous statement true, which was my main argument all along.
BTW, you can do this in VS.NET and most likely VC6:
struct Test { int x; };
int _tmain(int argc, _TCHAR* argv[])
{
Test& ref = *((Test*)NULL);
return 0;
}
No crash, no nothing. Yet, ref will reference "an object" at NULL. Put a breakpoint on return 0 and you'll see.
I still believe that the only advantage of references over pointers are purely syntactical.
--
There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees.
We call it master and servant.
|
|
|
|
|
That is a bug in the program which is a different beast. As the standard states, a well defined program can't have a NULL reference where a pointer can have a NULL pointer.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Yes, it was a bug - and what software is 100% bug free?
Tim Smith wrote:
As the standard states, a well defined program can't have a NULL reference where a pointer can have a NULL pointer.
True. But just as pointers can be dangling, references can too as I demonstrated.
NULL is just one "bad" value out of 232 possible values on a contemporary 32 bit machine. Most of the other 232 - 1 aren't (most likely) legal.
I am arguing that the statement "if you pass by reference, you are sure that the class/struct is valid" is false - something which I believe I demonstrated with perhaps an easy to spot "error". However, as you point out, a reference can't ever be NULL1.
1 In an environment where you can do *((SomeClass*)NULL) = SomeClass();, what is SomeClass& ref = *((SomeClass*)NULL);? You could, if you really wanted to, do that in DOS.
--
There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees.
We call it master and servant.
|
|
|
|
|
It certainly is possible to pass a reference to NULL:
struct Stuff {
...
};
void StuffFunction(Stuff &stuff_item);
...
Stuff *stuff_pointer = NULL;
StuffFunction(*stuff_pointer); The compiler treats the "reference to dereferenced pointer" object as an 'identity' case, and just passes the value of the pointer, which in this case is NULL. In this case, inside the StuffFunction you can't tell that NULL has been passed in.
The point behind the debate is that references are not inherently 'safer' than using pointers. They can be syntactically more convenient. Pointers are easier to get sloppy with if you're not careful.
Software Zen: delete this;
|
|
|
|
|
Gary R. Wheeler wrote:
It certainly is possible to pass a reference to NULL:
I know, I tried it in VS.NET the other night. I was just too tired to mention it, and it didn't really have any relevance with respect to my argument.
Gary R. Wheeler wrote:
In this case, inside the StuffFunction you can't tell that NULL has been passed in.
Well, you could always do if(&stuff_item == NULL) , assuming Stuff doesn't override operator& .
Gary R. Wheeler wrote:
Pointers are easier to get sloppy with if you're not careful.
The only extra support a reference gives you is that you have to initialize it. Which is certainly nice since the compiler can yell Error!
I think I'll experiment some tomorrow to see if I can eliminate the use of pointers (to see if it's possible). I have some ideas I want to try out...
--
There's a new game we like to play you see. A game with added reality. You treat me like a dog, get me down on my knees.
We call it master and servant.
|
|
|
|
|
When using non-dynammically allocated structures or when accessing elements of an array, the reference version is easier and visually cleaner. Also, it would be wise to place consts on both those arguments to provide hints to the compiler.
References really start to shine when you start getting into operator overloading.
Tim Smith
I'm going to patent thought. I have yet to see any prior art.
|
|
|
|
|
Ah yes, lpObject->operator[](index) is rather ugly, huh? So as far as I can see, there is no real reason to use one over the other, other than for cleanliness of the code. As for the consts, I got you on that one -- neither can be const since they are both modified by the called function.
Thanks everyone for the responses.
--Dean
|
|
|
|
|
Hi all,
I know this is a Visual C++ forum but there is no other forum for other C++ compilers and I already posted this in the C# forum and they didn't aprove. However this might be a very easy question and a commen topic and I know there is a lot of info on it but I could not find a single tutorial or artical for creating and using a dll in Dev-C++, I am using the latest version 5.0 beta 7 (4.9.7.0). I know there is a project template type dll to select and most of the code is ready but I can't understand it and there is nothing written in the help documents. And the worst part is there is nothing on how to use the compiled dll . The reason why I choose Dev-C++ for my dll is becouse I love it and it is so easy to use, except for this part maybe , and I have already written the program that the dll is for in Dev-C++. I heard on the site www.functionx.com/visualc/applications/staticdll.htm from FunctionX that dlls compiled in Visual C++ can't simply be "plugged" in programs written in Dev-C++ and Borland C++, is that true? And how do I use and create a dll in Dev-C++?
Aidman » over and out
|
|
|
|
|
I have a .txt that has a list of file names. I am trying to write a program that opens the file, and performs the following commands to each file name in my list:
mkdir "filename"
gunzip "filename"
tar -xf "filename"
Thanks,
Lane
|
|
|
|
|
I don't mean to be contrary, but that seems to be something you would more likely want to write a script to do for you instead of a C program. I don't know perl well, but I believe that this is a trivial task with a perl script (I'm assuming you're using some version of *nix). Just google for "perl tutorial".
--Dean
|
|
|
|
|
You should have a look at the cmd.exe built in command "for". To be precise, "for /f".
|
|
|
|
|
Hi,
I am filling a list contol with items this way (so I can use the click on the column to sort)
<br />
LV_ITEM lvi;<br />
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; <br />
lvi.iItem = index; <br />
lvi.iSubItem = 0; <br />
lvi.iImage = 0;<br />
lvi.pszText = LPSTR_TEXTCALLBACK; <br />
lvi.lParam = (LPARAM) pItem;<br />
<br />
if (InsertItem (&lvi) == -1)<br />
return 0;
I am sure that I have a memory leak because I am not sure that all the stuff I added is being removed when I exit
Any idea.....
|
|
|
|
|
How do you know this is the location?
When(where) pItem gets deleted?
What does you text callback do (in terms of potential memory leak)?
|
|
|
|
|
That's the thing....
How can I get the pointer back in order to delete it ?
Here is how I get pItem:
<br />
DITEMINFO* pItem, *pMirror;<br />
try {<br />
pItem = new DITEMINFO;<br />
}
and here is the head of the function when I put the stuff inside the list control:
<br />
void CBadDrivesReportView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult) <br />
{<br />
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;<br />
<br />
if (pDispInfo->item.mask & LVIF_TEXT) {<br />
DITEMINFO* pItem = (DITEMINFO*) pDispInfo->item.lParam;<br />
<br />
switch (pDispInfo->item.iSubItem) {<br />
<br />
case 0:
::lstrcpy (pDispInfo->item.pszText, pItem->sn);<br />
break;<br />
.<br />
.<br />
.<br />
.<br />
.
I am looking for something like:
<br />
for (int i=0 ; i < Array.GetSize();i++)<br />
delete array.GetAt(i);
Thanks
|
|
|
|
|
You have to overwrite CListView::OnDestroy() (I assume CBadDrivesReportView is derived from CListView)
something like
void CBadDrivesReportView::OnDestroy()
{
for(int i = 0, count = GetListCtrl().GetItemCount(); i < count;++i)
delete (DITEMINFO*)GetListCtrl().GetItemData(i);
return CListView::OnDestroy();
}
|
|
|
|
|
Cool,
I will try it.
Thanks
|
|
|
|
|
is there any way to cast a CString to an Integer ?
for example i want to Cast "73264873287238" to 73264873287238
regards.
-=Ehsan-de-Burge=-
|
|
|
|
|
CString string_number="2323232323";
int real_number=atoi (string_number);
|
|
|
|
|
You can use atoi function.
Pavel
Sonork 100.15206
|
|
|
|
|
You should use the function atoi( const char *string ). There you can easily cast the CString, first casting it to LPCTSTR.
|
|
|
|
|
Hmmm ... seems like I wasted too much time writing my answer ... now you have the same solution for your problem 3 times. ;P
|
|
|
|
|
How do I prevent the current working directory from being changed after calling CFileDialog. Or when loading a file when the program starts up (called from the command line parameters)? This is really throwintg my program off course and thinking files are where they really aren't (i'm using the full path name when calling these files oddly enough.
-Steven
CP Addict
By reading this message you are held fully responsible for any of the mispelln's or grammer, issues, found on, codeproject.com.
For those who were wondering, actual (Linux) Penguins were harmed in creating this message.
|
|
|
|