|
Jochen Arndt wrote: But passing by pointer is technically passing by value. No it is not. The pointer points to a variable, it is not the value, but its address (i.e. a reference to it). Consider:
void PassByValue(int foo)
{
int i = foo + 5;
}
void PassByPointer(int* pFoo)
{
int foo = *pFoo; int i = foo + 5;
}
|
|
|
|
|
pFoo is a value of type int* . If you change pFoo inside the function, the value of pFoo will be changed (the address) but not the value of the variable it points to. Therefore, it is technically passing by value.
Compare this with a reference parameter int& foo . If you change foo , the value of the referenced variable will be changed but not the hidden address.
|
|
|
|
|
Jochen Arndt wrote: pFoo is a value of type int* No it is a pointer type, not a value type. And a reference type (which does not exist in C) is just a shorthand allowing you to modify a caller's value. But under the covers it behaves just the same as a pointer, thus:
void PassByPointer(int* pFoo)
{
*pFoo += 1; }
void PassByReference(int& rFoo)
{
rFoo += 1; }
|
|
|
|
|
A value is the content held by a variable. A pointer contains an address which is it's value.
|
|
|
|
|
Semantics.
|
|
|
|
|
I appreciate the clarification.
However, in school we used the & to indicate a reference in C. As in:
int PassByeReference(B& Parameter)
{
// Do something with B
}
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Standard C does not know about references.
Also, strict ANSI C does not know about // style comments, but many modern C compilers do.
Possibly you were using a C++ compiler to compile c code?
|
|
|
|
|
It was an early version of Borland Turbo C for DOS. Maybe they added the reference feature to the language?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
That seems unlikely. I tried the following here : https://archive.org/details/msdos_borland_turbo_c_2.01, and got the expected compilation error
#include <stdio.h>
void f(int &x) { x += 1; }
int main(void)
{
int n = 1;
printf("n = %d\n", n);
f(n);
printf("n = %d\n", n);
return 0;
}
According to cppreference.com, references were added as early as 1985, and the compiler used above was 2.0, (c) 1990. Its not impossible that Borland added references before that, but them removed them later. Or added them at a later date when their C++ tools came out.
|
|
|
|
|
I have learned C programming with Turbo C in the late 1980's and can't remember that it supported references.
Turbo C was discontinued as stand alone product in 1990 and the C compiler was included with Turbo C++ 1.0. So you probably used that.
|
|
|
|
|
Hi,
I am generating a CListCtrl in Report view (MFC). It loads fine and I can reorder columns by dragging the headers. I've made it so clicking a column header deletes the column - again this works fine except for the first (leftmost) column. Here the header is deleted but the data underneath doesn't change - in fact the data from the last column is deleted:
Before:
Header1 Header2 Header3
Data1 Data2 Data3
After trying to delete first column:
Header2 Header3
Data1 Data2
Having created the columns to begin with, I'm setting up the rest of the table like this:
void MyClass::InsertItem(int x, int y, CString &str)
{
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.iItem = y;
lvi.iSubItem = x;
lvi.pszText = (LPTSTR)(LPCTSTR)(str);
int result;
if(x == 0) {
result = mCSVListCtrl.InsertItem(&lvi);
}
else {
result = mCSVListCtrl.SetItem(&lvi);
}
}
which seems to create the table OK. Then when a header is clicked:
void MyClass::OnLvnColumnclickList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
mCSVListCtrl.DeleteColumn(pNMLV->iSubItem);
*pResult = 0;
}
Any ideas?
|
|
|
|
|
Either look using the debugger or put in a trace statement but make sure the sub item value is what you expect it to be.
That's the only idea I have because I know that calling DeleteColumn(0) works because I do it often. One of the weird things with the list control is you can't set the first column to be right-justified so the work-around is to add one more column than needed, set column 1 to be right-justified, and then delete column 0. BTW - this was true with older versions and I don't know if it is still necessary. I do it anyway because it still works.
|
|
|
|
|
Thanks for the various replies. The debugger doesn't go beyond DeleteColumn() but I can see it's passing zero. Can you see anything odd about the way I'm creating my sub items that could be causing the problem? I've created the columns first then for each item (row) I'm adding subitems left to right. Otherwise I'll have to go for the dummy first column option.
|
|
|
|
|
What happens if you create a "dummy" column 0 with a width of 0 (or maybe 1)?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
Not a solution to the problem but a tip.
Instead of deleting columns you might set the width to zero. Then you can implement a hide/show column handler (which requires storing the actual or a default width for each column when hiding to be restored when showing it again).
Note also that it might be necessary to get the effective column index when the columns has been reordered (GetColumnOrderArray ).
|
|
|
|
|
Member 868926 wrote: when a header is clicked:
void MyClass::OnLvnColumnclickList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
mCSVListCtrl.DeleteColumn(pNMLV->iSubItem);
*pResult = 0;
}
Any ideas?
Just for a test: what will happen if you call
mCSVListCtrl.DeleteColumn(0);
from anywhere but from this MyClass::OnLvnColumnclickList(...) message handler?
|
|
|
|
|
Victor Nijegorodov wrote: Just for a test: what will happen if you call
mCSVListCtrl.DeleteColumn(0);
from anywhere but from this MyClass::OnLvnColumnclickList(...) message handler?
It's the same. I think I'll have to go for the dummy left column idea some of you have suggested - maybe I'll use it to number the rows which might be quite nice anyway.
Thanks again for all your replies.
|
|
|
|
|
|
HI,
I have code that works fine in debug but I have already learned my lesson that it does mean It will work in Release
Anyway I got an assertion in wincore.cpp line 656 for having a window handle = NULL
After the message box came up pointing me to the location in wincore.cpp where the problem was I tried to attach the VS debugger with my solution.
Wasn't much help as the call stack was all windows code
One thing I did notice that was odd the DLL was MFC140d.DLL isn't that the debug version of MFC
I checked my property pages for release and I had /MD not /MDd shouldn't I have MFC140.DLL ??
|
|
|
|
|
Turn your warning level up .. it will give you uninitialized use warnings. The default is W3 go to W4 or WALL you might get a lot of warnings but saves you headaches
I usually start out W3 when it's getting close to release I crank the setting up and walk thru each warning.
What you are really saying is you have a bad habit of either using uninitialized variables or forgetting to initialize them which will be what your current problem is about. You need to work on getting rid of what is obviously a bad coding habbit.
/MD is the correct selection for the VC runtime library release but usually I go for /MT in release the exe gets bigger but no VC runtime install required on the target machine. Now I assume it follows thru to MFC I write so little on the MFC framework I can't say definitively. But yes usually in release /MD or /MT is the setting you would use the difference as stated, and if the blowup in size is worth not having to distribute the run-time library at all.
Now when VS debugs in release mode it's a quirky thing, as you stated you wanted no debug compilation but the VS IDE still tries to give you debug info. It seems to sort of guess at the line sometimes you will find it out by a line or 2 especially if it has optimized some of the code away. When running outside the IDE I know it only uses the correct DLL because the times I have used DLL distribution I only copy the one DLL for install.
In vino veritas
|
|
|
|
|
Thanks
I just realized I did a number of SetDlgItemText for labels in my Dialog but I never Created a window
Maybe I'll just have the appropriate CStatic's and use DDX_Control to initialize the windows handle
or better yet just use DDX_Text and put the data in a CString
Thanks
|
|
|
|
|
For some reason your release build is linked with the debug version of the MFC. You should find out why and fix that. A possible reason is linking with another DLL that depends on the MFC DLL and is a debug version itself.
With proper code, a debug build should also assert at that point (window handle NULL). However, it would not assert if the handle is not NULL but invalid (uninitialised variable). But then you usually get other runtime errors.
|
|
|
|
|
My only guess at this point that after doing various "new" to allocate heap storage to format labels for the dialog
I do AfxCheckMemory rather then assert to see if I some how over stepped my storage allocation
Thanks
|
|
|
|
|
This function works only in the Debug version of MFC. Therefore, it is common to call that within an ASSERT() .
Note also that you should check if the affected handle is on the heap. It does not help when it is on the stack.
|
|
|
|
|
I am quite sure the reason I got an assertion was because I did a SetDlgItemText without some how creating a m_hWnd
Just surprising that it worked at all under debug but then again I am beginning to understand the "debug" version covers up for a lot of mistakes
On more thing should assert only be used in "debug"
Thanks
|
|
|
|