How to print error in C++?

Page 3 - Seeking answers? Join the AnandTech community: where nearly half-a-million members share solutions and discuss the latest tech.

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
When I generate win32 window app, so I have these lines in the winapi.cpp:

Code:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
Should not these line be in the winapi.h when it just declares the functions which implementation is bellow?
By having them in the source code; they are essentially private functions; no other piece of code in a different file can call them

Also I sometimes see something similar:
Code:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, 
                // A POINTER TO DIALOG BOX PROCEDURE - declared on begin of this file
                (DLGPROC)About);
there is the DLGPROC and I don't understand if is is a type or macro defined in some header file? What this piece of code does
(DLGPROC)About
does it declare a type or what? Why the brackets must be there?
The (DLBPROC) declares the type of the About method to the DialogBox method. The initial definition of About is LRESULT CALLBACK
See bold answers
 

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
Also I want to ask you if do you agree with this DEFAULT order of thing in the code:
This is inside APIENTRY _tWinMain block:
Code:
// WHOLE THIS BLOCK LOOKS TO ME AS INITIATION SO WHY WOULD WE
    // SEPARATE ALL THE LINES FROM InitInstance ?
    MSG msg;
    HACCEL hAccelTable;
    // ESSPECIALLY THAT THESE STRING VARS ARE USED IN InitInstance()
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_WINAPI, szWindowClass, MAX_LOADSTRING);
    // AND THE CLASS REGISTERED HERE IS ALSO USED IN THE InitInstance()
    MyRegisterClass(hInstance);
    // SO THE ARRANGMENT OF THINGS HERE LOOKS ODD TO ME
    if (!InitInstance (hInstance, nCmdShow)) 
    {
        return FALSE;
    }
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WINAPI);
The InitInstance() basicly only creates the window with command:
Code:
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

How would you prefer arrangment of the code? Move the lines before into the IniIntstance() function or would you abort the IniIntstance() for clear arrangement?

Ask MS why they set it up.:p
 

h4ever

Member
Aug 30, 2013
163
0
0
Do you know why this does not work as I want?
http://paste.ofcode.org/7zCSzeznsQgyiFaakEftMD


Code:
    case WM_LBUTTONDOWN:
        hdc = BeginPaint(hWnd, &ps);
        OnLeftButtonDown(hdc);
        EndPaint(hWnd, &ps);
    break;
    case WM_RBUTTONDOWN:
        hdc = BeginPaint(hWnd, &ps);
        OnRightButtonDown(hdc);
        EndPaint(hWnd, &ps);
    break;
Should draw but there is still the only one drawing. Should I need to update window or what?

The HatchBrush and and OnRightButtonDown functions were called from OnPaint originally
 
Last edited:

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
What is actually happening in the On***ButtonDown? Are you doing some graphics drawing?
If so, you need to Invalidate the screen area where the graphics was being done.
 

h4ever

Member
Aug 30, 2013
163
0
0
Drawing into Window client area. There is graphics right now and I want to redraw it with new one.
 

h4ever

Member
Aug 30, 2013
163
0
0
I already did this (according tutorial lesson 7) :
Code:
        case WM_PAINT:
            OnWM_PAINT();
        break;
        case WM_MOUSEMOVE:
            OnWM_MOUSEMOVE(wParam, lParam);
        break;
        case WM_RBUTTONDOWN:
            DrawIntoClientArea(wParam, lParam);
        break;
        case WM_LBUTTONDOWN:
            DrawIntoTitle(wParam, lParam);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
And that works OK.

But in the lesson 17:


Code:
    switch (message) 
    {
    case WM_LBUTTONDOWN:
        hdc = BeginPaint(hWnd, &ps);
        OnLeftButtonDown(hdc);
        EndPaint(hWnd, &ps);
    break;
    case WM_RBUTTONDOWN:
        hdc = BeginPaint(hWnd, &ps);
        OnRightButtonDown(hdc);
        EndPaint(hWnd, &ps);
    break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        OnPaint(hdc);
        EndPaint(hWnd, &ps);
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
    break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
does not work.

Also I cannot make working the invalidate()
how to include? Also why I should needed that when the code from lesson 07 works? I found this:
You're missing MFC to get afxwin.h and the Platform SDK for <windows.h>. They don't come included with the Express edition.
But I have express edition and would wonder if this drawing stuff could not work.
 

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
The paint structure contains a RECT data structure that has the smallest rectangle that completely encloses the update region and a flag that specifies whether the background has been erased.

The update region is set by the Invalidate, InvalidateRect, or InvalidateRgn member functions and by the system after it sizes, moves, creates, scrolls, or performs any other operation that affects the client area. If the update region is marked for erasing, BeginPaint sends an WM_ONERASEBKGND message.

Do not call the BeginPaint member function except in response to a WM_PAINT message. Each call to the BeginPaint member function must have a matching call to the EndPaint member function. If the caret is in the area to be painted, the BeginPaint member function automatically hides the caret to prevent it from being erased.

From the definition of CWnd::BeginPaint

Based on your code and the last paragraph quoted, you are not obeying the rules.
 

h4ever

Member
Aug 30, 2013
163
0
0
So the BeginPaint is not possible to use outside of WM_PAINT even if I would have MFC?

So just to make it clear, when I would have MFC and would use WM_PAINT to redraw graphics, the Invalidate() should be called before I start to draw new graphics, right?

Ok, then, and if I don't use MFC, and I need to clear graphics from the window?
 
Last edited:

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
MFC is just a wrapper around the Win32 API.

BeginPaint is Win32 method used to setup internally the redrawing parameters
 

h4ever

Member
Aug 30, 2013
163
0
0
OK, I'm getting back to original project AOKTS because I see I wont solve this and it is more beneficial to do something what I really need than playing with drawing. I study the source code of AOKTS again and I found this piece of code, maybe you could explain (I maybe already asked this but I don't remember where and don't remember where you replied about the character L). I did not find declaration of the L... it looks like it could be some type declaring the text to be passed in the struct (?). I see he defined a macro PF, but what the macro does? What is the result? Is this some way of definition of structure? I meant the elements of ESDATA.

Code:
#define PF(n, f) { n, f }    //I just prefer this syntax
ESDATA::pFunc ESDATA::pfuncs[] = 
{
    PF(L"tech", &ESDATA::readTech),
    PF(L"color", &ESDATA::readColor),
    PF(L"protounit", &ESDATA::readUnit),
    PF(L"resources", &ESDATA::readResources),
    PF(L"simple", &ESDATA::readSimple),
    PF(L"aitypes", &ESDATA::readAitypes),
    PF(L"terrain", &ESDATA::readTerrain),
    PF(L"group", &ESDATA::readUnitGroup),
    PF(L"civ", &ESDATA::readCiv),
    PF(NULL, NULL)
};
From the ESDATA definition:
Code:
 extern class ESDATA
{
    static struct pFunc
    {
        const wchar_t * name;
        void (ESDATA::*f)(const XML_Char **attrs);
    } pfuncs[];
....
}
Also please tell me what does it mean when you use convention like this, where two things are separated by space:
Code:
 ESDATA::pFunc ESDATA::pfuncs[]

Also, if you can check the file esdata.h in model folder, can you explain me how it is possible that object _tail has function or has access to function setNext? I found this line: _tail->setNext which was not declared in the header as part of _tail, but setNext is function of Link class and _tail is private property of LinkList class/template.
 
Last edited:

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
if you notice they are using const wchar_t * name;

this is a wide character (16 bits, not 8 bits)
The use of the L"text" indicates that the text should be treated as a wide character string/array
 

h4ever

Member
Aug 30, 2013
163
0
0
Can you tell me, when a function is called in C++, where are copied its parameters? Into stack or into heap?
 

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
No idea. I suspect not heap because in debugger, you can see the parameters themselves.

It should not make a difference at that level of coding.

One can control if variables are to be assigned to a register, but unless you know what you are doing ...
 
Last edited:

code65536

Golden Member
Mar 7, 2006
1,006
0
76
Can you tell me, when a function is called in C++, where are copied its parameters? Into stack or into heap?

No calling convention uses a heap. Heaps are complicated, expensive, and the very usage of a heap requires a function call of its own. Plus, they are implemented in runtime or system libraries and not in the language itself--heck, the Windows system libraries gives you half a dozen different types of heaps to choose from, and you can even create your own heap implementation if you want (which is what Firefox does, for example).

The question really should be whether parameters are passed on the stack or via registers, and the answer to that is that it depends on the calling convention, and there are lots of them in Windows.
 
Last edited:

h4ever

Member
Aug 30, 2013
163
0
0
Thanks code65536. But there is still something what I am not sure of. I give example with this class (just declaration to make it shorter).

Code:
class Vektor
{
  private:
     int [B]*myArray[/B];
  public:
     Vektor();
     Vektor(int myArraySize);
     ~Vektor();
     void calc([B]const [/B]Vektor [B]secondVectorAliasTempVector[/B]);
     void setElementsOfArray(int Val);//just to set some values to the array
};

Now, lets skip the part of definition of constructor and methods; here is the implementation:

Code:
Vektor v1(4),v2(4); // Create vectors v1 and v2
   int p;
   for(p = 0; p<4; p++) // Set the elements of v1 a and v2 private arrays 
   {
      v1.setElementsOfArray(p);
      v2.setElementsOfArray(p);
   }
   v1.calc(v2); // Inside this function is ERROR!

(note I did not test this, because I rewritten the code from that one in my local language and got simplify it; this is just for illustration).

What is not clear to me is, in this case, is the private member v2.myArray copied completely into memory*? Or is it just the pointer pointing to v2.myArray what is copied? It makes to me no sense, why not to keep the pointer to v2.myArray saved in the secondVectorAliasTempVector.Array pointer...I thought that object or array should be reffered by reference automatically. *So if this is not copied by reference, so it results in error when the function call is finished. v1.Array will not point to nowhere because the secondVectorAliasTempVector.Array was removed from memory.
 

code65536

Golden Member
Mar 7, 2006
1,006
0
76
When you pass an object to a function, it's passed by value unless specified otherwise. Internally, what this means is that the compiler inserts code to create a duplicate copy of that object. So what looks like a simple function call is actually the following:
1) Allocate memory with a function call to the new operator and create an object in this memory.
2) Another function call the copy constructor for the object's class. If no copy constructor is specified, use the default copy constructor.
3) This, in turn, makes copies of everything belonging to the class, and if the class has objects, those, too, are duplicated in a similar fashion.
4) This newly-created object is then passed to your function (internally, it's the pointer of this new object that gets passed).

So what appears to be a simple function call is actually compiled into a series of function calls as objects and objects inside objects are duplicated.

But note that when you have a pointer (int *myArray), that's a primitive, not an object, so the duplication code just duplicates the pointer, not the memory pointed to by the pointer (as in, the new object has a pointer that points to the same address).


(This is why I think C++ is a horrible language; it obfuscates and makes implicit things that really ought to be explicit. If you need to do systems programming, use C (or C++ without the OOP parts). If you need higher-level constructs like object orientation, use a language like C# or Java that was designed for that kind of thing. C++ is a messy Frankenstein language.)
 

h4ever

Member
Aug 30, 2013
163
0
0
So what looks like a simple function call is actually the following:
1) Allocate memory with a function call to the new operator and create an object in this memory.
2) Another function call the copy constructor for the object's class. If no copy constructor is specified, use the default copy constructor.
3) This, in turn, makes copies of everything belonging to the class, and if the class has objects, those, too, are duplicated in a similar fashion.
4) This newly-created object is then passed to your function (internally, it's the pointer of this new object that gets passed).

I decided to delete the replay on this post, because, I read some article which confused me. But now the things are clear to me so I better deleted my reply, not to make chaos in discussion.
 
Last edited:

EagleKeeper

Discussion Club Moderator<br>Elite Member
Staff member
Oct 30, 2000
42,589
5
0
If you have a CONST array being passed to a method and that method attempts to modify data within the array; you are breaking the "contract" of the CONST.

Understand what the purpose of CONST is; to either lock the data or the address depending on how it is used.

What is the code inside calc?
 

h4ever

Member
Aug 30, 2013
163
0
0
The basic idea of the example above is create two objects, having two private arrays with some integers. You set some numbers to those arrays and then you call calc. The calc can make any mathematical operation and v1.calc()should change v1, not v2. So v1.calc(v2); should read the values in v2.myArray, and then for example to add these values to v1.myArray. This should not matter how you effect the v1. It should even not matter if the calc code is empty. The basic idea of the code was to illustrate how the v1 pointer will point to nowhere because it has been overwitten with pointer to temporal copy of the v2 object. This happens when the v2 object is copied from input param into the memory. When the temporal object is removed from memory, in that moment we have no valid pointer v1.myArray. So, now as I understoond the const correctly (while been reading article about defining my own operator) I know that the const really does not mind in this case, and the const just says, v2 will not be changed (secondVectorAliasTempVector will not be changed).
 
Last edited:

mv2devnull

Golden Member
Apr 13, 2010
1,526
160
106
What you describe is copy constructor. But I asked about no use of copy constructor, so only CONST used. I tell you what makes me confusing. When you use CONST, the array is not copied into the temporal object.
...
YOU AND OTHERS told me that the array is not copied.
You have been told something, and you have understood something. But were they apples and oranges?

Array parameters to function are one thing. Your Vektor is not an array. It might contain arrays, but that is irrelevant.
Code:
void foo( T b );  // copy constructor is called
void foo( const T b );  // copy constructor is called, b is const within foo
void foo( const T & b );  // no copy, b refers to callers memory location but cannot modify it
void foo( T * b );  // copy address, b points to callers memory location
void foo( T & b );  // no copy, b refers to callers memory location
void foo( T[] b );  // no copy, b is an array
 

h4ever

Member
Aug 30, 2013
163
0
0
mv2devnull:
There was some confusion on my side, but that was about some terms in the article which I read. I know Vektor is class. Thanks for the code.

So I understand this:
copy constructor is essentially a new instance.
Code:
 MyClass m; // copy constructor which creates new instance

Code:
myFirstInstance.myMethod(MyClass m); // copy constructor which creates new temporal instance, which is created in the memory reserved for the function call.
myFirstInstance.myMethod(MyClass &m); // will create reference to the object passed to function
myFirstInstance.myMethod(const MyClass &m); // same - will create reference to  the object passed to function - but m cannot be changed
 
Last edited:

mv2devnull

Golden Member
Apr 13, 2010
1,526
160
106
Almost.
Code:
MyClass m;
This is a declaration of a variable 'm' of type MyClass. Variable is created right here and since no data is passed to it for initialization, the default constructor of MyClass is called.
Code:
MyClass x{ m };
Another variable, but this one is initialized with a value. Since 'm' has type MyClass, a call to copy constructor is likely.

Now, lets have a function and use it:
Code:
void foo( MyClass x )
{
  int z = 42;
  ...
}


MyClass m;
foo( m );
We could this time for demonstration purposes inline the function, i.e. write it directly into the calling code like this:
Code:
MyClass m;

{
  MyClass x{ m }; // copy construction
  int z{ 42 }; // copy construction
  ...
}
A function call reserves space from stack for return value, parameters, and local variables of the function very similarly. The parameter variables are initialized from the arguments that the caller uses.

I would not call a parameter "temporary", because it has name and it does live until execution returns from the function, just like the local variables in the function.

This code may contain a genuine nameless temporary variable:
Code:
a = b + c;
 

h4ever

Member
Aug 30, 2013
163
0
0
mv2devnull:
Do you find something wrong in my last post? Because I do not find any problem in your and my post. I think I needed to realize that the declaration
Code:
MyClass m;
is exactly same as creating of new instance. But what I did not realized before, was that it can occure in function parameter with same meaning. I called it temporal because the article which I read showed the problem with pointers and how we can lost the valid data in a pointer. So this is the reason why I called it temporal, because the pointer will refer to those "temporal" data. When they are removed from memory, we got invalid pointer (pointer with no valid reference / no valid data can be found there).
 
Last edited: