warning C4020: 'CreateVertex' : too many actual parameters - visual-c++

What does that warning says?
I could not find any typos or extra characters in the code.:
if (!(connectedComp = (Vertex**)malloc(sizeof(Vertex*)))) {
AllocationError();
}
if (!(created = (unsigned int*)malloc(sizeof(unsigned int)))) {
AllocationError();
}
connectedComp[++counter] = CreateVertex(id, edgesMatrix, maxValue, created);
I declared
Vertex** connectedComp = NULL;
and the function signature is:
Vertex* CreateVertex(unsigned int id, unsigned int** edgesMatrix, unsigned int maxValue);
Thanks in advance,

Function prototype of CreateVertex has 3 arguments and you are trying to send 4. That is the warning

Well your function signature is
Vertex* CreateVertex(unsigned int id, unsigned int** edgesMatrix, unsigned int maxValue);
And you are passing 4 arguments. This is the problem and hence compiler is giving the following compilation error.
connectedComp[++counter] = CreateVertex(id, edgesMatrix, maxValue, created);
By looking your code your call should be
connectedComp[++counter] = CreateVertex(id, edgesMatrix, maxValue);
BTW, you should avoid using malloc/free in C++ instead of that use new/delete or smart_pointer mechanism.

Related

LPNMITEMACTIVATE and code analysis (C26462)

Why is it that in the source code in the SDK for LPNMITEMACTIVATE it is defined with the asterix to the left?
typedef struct tagNMITEMACTIVATE
{
NMHDR hdr;
int iItem;
int iSubItem;
UINT uNewState;
UINT uOldState;
UINT uChanged;
POINT ptAction;
LPARAM lParam;
UINT uKeyFlags;
} NMITEMACTIVATE, *LPNMITEMACTIVATE;
I am always used to the pointer being on the right. Either way, code like:
const LPNMITEMACTIVATE pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
Will still flag a const (C26462) warning:
If I change the code to:
const NMITEMACTIVATE* pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
The warning will go away.
I tried this with Visual Studio 2022, first of all, warning C26462 was not enabled by default. Perhaps you are using an earlier release, or there is something odd with my installation.
After manually enabling the warning, I could make that warning go away by assigning pNMItem more than once:
LPNMITEMACTIVATE pNMItem = nullptr;
pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
How is this useful?
Or it can be fixed as suggested in other answers. But you may have additional problem because pNMHDR was probably declared as LPNMHDR, so you have to rewrite more lines:
NMHDR hdr = { 0 };
const NMHDR* pNMHDR = reinterpret_cast<NMHDR*>(&hdr);
const NMITEMACTIVATE* pNMItem = reinterpret_cast<const NMITEMACTIVATE*>(pNMHDR);
This can be a big waste of time. Note, the extra compliance is recommended if you are writing code that's supposed to run on any system. But MFC is tied to Windows so this isn't really an issue. MFC and Windows are still using that "long pointer" crap that's left over from 16-bit Windows, they are not compliant themselves, so consider turning off some of these warnings.
This is standard C/C++
Like in this (not runnable) code snippet:
typedef int *LPINT;
// typedef int* LPINT; // you could write this, it's exactly the
// the same as above
int main()
{
LPINT pint;
int* pint2;
*pint = *pint2;
}
pint and pint2 are both pointers to int. BTW this is hiding a pointer type behind a typedef, which is a bad idea (but was considered as a good idea in old MS days), but lots of Microsoft headers still have these typedef sometype *LPsometype; typedefs for compatibility reasons.
Another example which is closer to the MS header you're refering to:
This:
typedef struct tagNMITEMACTIVATE
{
int hdr;
int iItem;
} NMITEMACTIVATE, *LPNMITEMACTIVATE;
is equivalent to this:
typedef struct tagNMITEMACTIVATE
{
int hdr;
int iItem;
} NMITEMACTIVATE;
typedef struct tagNMITEMACTIVATE *LPNMITEMACTIVATE;
For pointer const can be applied to the type the pointer points at:
const NMITEMACTIVATE* p;
or
NMITEMACTIVATE const* p;
Or it can be applied to the pointer variable itself:
NMITEMACTIVATE* const p;
Now if you have typedef:
typedef NMITEMACTIVATE *PNMITEMACTIVATE;
The const would not apply to the type being pointed at. Either way it is the pointer itself is constant:
const PNMITEMACTIVATE p;
PNMITEMACTIVATE const p;
To avoid this confusion, prefer not to use raw pointer typedefs (and not to define them).

How to avoid Conflict of defined seconds() method and ptime seconds(default) method?

Here unsigned long EVTime::seconds() method is conflicting with ptime p(d,seconds(s));. If I change ptime seconds(s) to minutes/hours then it works fine.
If i change that seconds(s) to minutes(s) or hours(s) then only it will work. I am new to C++, anyone please help to resolve this conflict.
evt.cpp:
unsigned long EVTime::seconds()
{
ptime t(date(1901,Jan,1),time_duration(0,0,0));
time_duration td = utcdatetime - t;
return (unsigned long)td.total_seconds();
}
EVTime::EVTime(unsigned long s)
{
date d(1901,1,1);
ptime p(d,seconds(s));
utcdatetime=p;
}
evt.h:
class EVTime
{
public:
EVTime(unsigned long s);
unsigned long seconds();
ptime utcdatetime;
};
main.cpp:
int main()
{
EVTime t(222l);
cout<<"seconds since 1901: "<<t.seconds()<<endl;
}
Error code:
evtime.cpp: In constructor ‘EVTime::EVTime(long unsigned int)’:
evtime.cpp:35: error: no matching function for call to ‘EVTime::seconds(long
unsigned int&)’
evtime.cpp:14: note: candidates are: long unsigned int EVTime::seconds()
Your function seconds() takes no parameters, but you send it s when you call it: ptime p(d,seconds(s));
This causes the error "no matching function for call to EVTime::seconds(long unsigned int&)", since you don't have a matching function.
Either call ptime p(d,seconds()); or change the seconds function signature to take the parameter and do something with it.

Erase a specific character from a given string C++11

I would try to remove a specific character from a given string in the following code.
int main(void){
string query="a*de*da";
string org;
uint8_t rmc='*';
std::vector<string::const_iterator> wpos;
for(string::const_iterator itr = org.begin();
itr!=org.end();
++itr){
if(*itr==rmc){
wpos.push_back(itr);
}
}
uint64_t wcnt=0;
for(auto witr: wpos){
org.erase( witr-(wcnt++) );
}
query=org;
return 0;
}
In this code, I would expect that query="adeda" however, I got an error
error: no matching function for call to ‘std::basic_string<char>::erase(__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >)’
org.erase(witr-wcnt);
My experimental setting is g++ 4.9.2 of devtoolset-3 on CentOS6.7
From C++98 to C++11, the signature of std::string::erase changed from
iterator erase(iterator p)
to
iterator erase(const_iterator p)
It seems like g++4.9.2 still uses the old version. Your example should compile if you change string::const_iterator to string::iterator.

std::string.c_str() returning a weird characters

In my project, I use to load textures by specifying its file name. Now, I made this function const char* app_dir(std::string fileToAppend); that returns the mains argv[0] and change the application name by the fileToAppend. Since I cannot make the string manipulation easy with a char*, I use the std::string. My texture loader takes a const char* for file name so need to switch back to c_str(), now it generates a sequence of ASCII symbol characters (bug). I already fix the problem by changing the return type of the app_dir() to std::string. But why is that happening?
EDIT
sample code:
//in main I did this
extern std::string app_filepath;
int main(int argc, char** arv) {
app_filepath = argv[0];
//...
}
//on other file
std::string app_filepath;
void remove_exe_name() {
//process the app_filepath to remove the exe name
}
const char* app_dir(std::string fileToAppend) {
string str_app_fp = app_filepath;
return str_app_fp.append(fileToAppend).c_str();
//this is the function the generates the bug
}
I already have the functioning one by changing its return type to std::string as I said earlier.
A big no no :) returning pointer to local objects
return str_app_fp.append(fileToAppend).c_str();
Change your function to
std::string app_dir(const std::string& fileToAppend) {
string str_app_fp = app_filepath + fileToAppend;
return str_app_fp;
}
And on the return value use c_str()
When you using function const char* app_dir(std::string fileToAppend); you get pointer to the memory that allocated on the stack and already deleted when the function ends.

Why aren't these arguments valid?

//Block.h
#pragma once
class Block
{
public:
CRect pos;
int num;
public:
Block(void);
~Block(void);
};
//view class
public:
Block currentState[5]; // stores the current state of the blocks
void CpuzzleView::OnDraw(CDC* pDC)
{
CpuzzleDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//draw the 4 blocks and put text into them
for(int i=0;i<4;i++)
{
pDC->Rectangle(currentState[i].pos);
// i'm getting an error for this line:
pDC->TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
}
pDC->TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
The error says that no instance of overloaded function CDC::TextOutW() matches the argument list . But the prototype for the function is:
CDC::TextOutW(int x, int y, const CString &str )
all i've done is that instead of the 2 points i've directly given the point object returned by CenterPoint() ... shouldn't it work?
That's because you didn't supplied arguments list correctly. Please read compiler error message carefully, it's usually helps to solve the problem.
TextOut(currentState[i].pos.CenterPoint(), currentState[i].num);
In this call you passed CPoint object and int. This is not correct, you need to pass int, int and CString (or const char* and int length).
To fix this you shall do something like this:
CString strState;
strState.Format("%d", currentState[i].num); // Or use atoi()/wtoi() functions
TextOut(currentState[i].pos.CenterPoint().x, currentState[i].pos.CenterPoint().x, strState);

Resources