Trouble with templates and for loops - c++

I have this code, which is giving me a single error that indicates two problems.
int healthyConst = 0;
int sickConst = 1;
int recoveredConst = 2;
GraphMatrix<int, double> graph (100);
for (int i = 0; i < sampleSize; i++)
{
if(std::rand() % 2 > 0.05) graph.setVertexInfo(i, sickConst); //Error
else graph.setVertexInfo(i, healthyConst);
}
The error is:
error: no matching function for call to GraphMatrix::setVertexInfo(int&, int*)
And the function in question is declared as follows in the source:
void GraphMatrix::setVertexInfo(int v, VertexObject& info)
First, i should not be a reference. This seems nonsensical to me, yet I can not fix this. If I try to outsmart the compiler and type for(int* i = 0...) the error now complains of setVertexInfo(int&*, int*), and I don't even understand what this means.
Second, sickConst is not a pointer. It is just an int. Now I realize the method, as written, accepts VertexObject&, not VertexObject, but *sickConst also causes the compiler to complain of invalid type argument of 'unary *'. I've also tried &sickConst, which the compiler not unexpectedly interprets as a pointer.
Also note, identical errors are thrown for the second line of the for loop, presumably for the same reasons.
The question is: why am I getting these errors, and how do I fix them?

You stated that your function declaration within the source is as follows:
void GraphMatrix::setVertexInfo(int v, VertexObject& info)
However in your for loop you are passing it a type of int. Either change your function declaration & definition to accept a type of int or change the type that you are passing to your function as a VertexObject.

Related

C++ Cast from ‘std::__tuple... {aka ‘unsigned int*’} to ‘uint32_t’ {aka ‘unsigned int’} loses precision

You may have to forgive me as I'm new to C++ and may have made some fundamental errors with the code I have worked up so far.
static tuple<read_result, uint8_t*> m_scan_record(bool skip, uint32_t& size, FILE* file)
{
read_result result;
tuple<read_result, uint32_t*> rd_rec_size_result = m_read_generic_t<uint32_t>(file);
result = (read_result)get<0>(rd_rec_size_result);
if (result != read_success )
{
return tuple<read_result, uint8_t*>(result, nullptr);
}
size = (uint32_t) get<1>(rd_rec_size_result);
if ( skip )
{
fseek(file, size, SEEK_CUR);
}
// ...
}
template<typename T>
static tuple<read_result, T*> m_read_generic_t(FILE* file)
{
T ret = 0;
read_result result = m_read_from_file_to_buffer(&ret, sizeof(T), file);
if (result == read_success)
{
return tuple<read_result, T*>(result, &ret);
}
return tuple<read_result, T*>(result, nullptr);
}
When I compile this code I am getting this error:
cast from ‘std::__tuple_element_t<1, std::tuple<read_result, unsigned int*> >’ {aka ‘unsigned int*’} to ‘uint32_t’ {aka ‘unsigned int’} loses precision [-fpermissive]
My intentions and what I am expected to do/happen:
In the declaration of m_scan_record, the size argument is declared with a & which is intended to allow me to pass the value by reference, analogous to using the REF c# keyword
I make a call to generic (template) function m_read_generic_t which is called with the specified type <unit32_t> and therefore (according to its definition) will return a type of tuple<read_result, uint32_t*>
Once I have the tuple returned by m_read_generic_t, I want to take the unit32_t value pointed to by the second value of the tuple, and put that value into the size variable mentioned at point 1, above, which presumably will then be accessible to the calling function one step further up the stack.
From the above points you can hopefully see that my intention (and I appreciate that I may be far away in reality!) is that at this line:
size = (uint32_t) get<1>(rd_rec_size_result);
all I am doing is simply grabbing a 'pointed to' value and putting it into a variable of a matching type, much like the oft-cited textbook example:
uint32_t v = 123;
uint32_t* ptr_to_v = &v;
uint32_t x = ptr_to_v; // x == 123
Clearly this is not what is really going on with my code, though, because if it were, I presume that the cast would be un-needed. But if I remove it, like this:
size = get<1>(rd_rec_size_result);
then I get a compile-time error:
a value of type "std::__tuple_element_t<1UL, std::tuple<read_result, uint32_t *>>" cannot be assigned to an entity of type "uint32_t"
I believe therefore that I am doing something badly wrong - but I can't work out what. Is this to do with the way I am taking the pointer out of the tuple; or is there something else going on when it comes to the getting a uint32_t value from a uint32_t* ?
This is all in a C++ environment on Ubuntu 20.04, FWIW
Many thanks in advance for any/all suggestions; please go easy on me!
tuple<read_result, uint32_t*> rd_rec_size_result = ...
The 2nd member of this tuple, as explicitly declared here, is a pointer to a uint32_t. That's what uint32_t * means, in C++.
size = (uint32_t) get<1>(rd_rec_size_result);
This retrieves the uint32_t * and attempts to convert it to a uint32_t. C++ does not work this way. Although this conversion can be forced your compiler has every right to believe that whatever this code is trying to do it must be wrong.
Perhaps I was wondering initially, your intention was to dereference the pointer. This is the reason for your compilation error, in any case. If your intention was to, truly, dereference this pointer, then this would've been a simple matter of changing this to
size = *get<1>(rd_rec_size_result);
However, that's not going to be the end of your troubles. Even after this compilation error is fixed, this way, the shown code will still be badly, badly broken.
This is because m_read_generic_t returns a pointer to a local object, which will get destroyed when the function returns, and attempting to dereference this pointer, here, will make demons fly out of your nose.
The real fix here is to change m_read_generic_t to not return a pointer as the 2nd value in the tuple in the first place, thus eliminating the compilation error in the first place.

Call to 'abs' is ambiguous in Objective-C++

I have a problem in this code snippet, it is giving the error call to 'abs' is ambiguous.
for (NSUInteger idx = 0; idx < count; idx++) {
if ((std::abs(toValues[idx] - previousValues[idx]) >= t) || (std::abs(previous2Values[idx] - previousValues[idx]) >= t)) {
return false;
}
return true;
}
There are two possible causes for call to some_function() is ambiguous.
Arguments in a function call do not match those in any function
declaration.
I hope the arrays toValues and previousValues are of the same type. In this case check if the value toValues[idx] - previousValues[idx] is of a type that is allowed by abs() as an argument. According to C++11 standard the allowed values are int, long int and long long int.
Perhaps you could cast the value of the toValues[idx] - previousValues[idx] to integer or another permitted type to rule out this as a cause like below :
(int)toValues[idx] - previousValues[idx]
The same function is defined more than once
abs() is a massively overloaded function. You could check if it is included multiple times in your code using multiple header files. For example inclusion of math.h and cmath.h will result in a duplicate abs() function which will lead to ambiguity. However, such inclusion of headers does not make any sense. Rather such inclusion is accidental.

How to call a function from header file in c++

I'm new in C++
I was using java before, I'm trying to call a function in c++ from a hearder file.
Here is my code:
sum.h
int sum(int a, int b);
cur_time.h
#ifndef CUR_TIME_H
#define CUR_TIME_H
clock_t clock(void);
#endif /* CUR_TIME_H */
main.cpp
#include <iostream>
#include "sum.h"
#include "cur_time.h"
int main ()
{
int x;
int y;
x = sum(3,4);
std::cout << x;
y = clock(void);
y = std::cout << y;
return 0;
}
So in main.cpp I try to display the elapsed time of my system with this function: clock_t clock(void);
When I run the project, I have this error:
main.cpp:13:13: error: expected primary-expression before ‘void’
main.cpp:14:3: error: ‘__ostream_type’ was not declared in this scope
If I run the code without calling the second function it works for sum.
You don't have to (and mustn't) use void in parentheses on calling a function.
assigning std::cout << y to y is meaningless here and gcc gave me this error:
error: invalid user-defined conversion from 'std::basic_ostream' to 'int' [-fpermissive]
Therefore, main.cpp should be like this:
#include <iostream>
#include "sum.h"
#include "cur_time.h"
int main ()
{
int x;
int y;
x = sum(3,4);
std::cout << x;
y = clock(); // remove void
std::cout << y; // remove y =
return 0;
}
Have you defined your sum(int, int) function in Sum.h?
Simply doing int sum(int a, int b); is not good enough, you need to define that function.
int sum(int x, int y) {return x+y;}
Let's take that first error message as a clue. I encounter it a LOT, in various forms, when I write C++ code.
main.cpp:13:13: error: expected primary-expression before ‘void’
The phrase "expected primary-expression" almost always means that you have A) forgotten something, or B) typed something weird or unexpected.
For example, you will get the same kind of error if you were to try cout << "Hello, " < "world!" << endl; In that case, I put a < where I should have put a <<. (Actual example from my code two days ago.)
In your case, the error message is screaming about void, which means that void or whatever precedes it is out of place. In your line y = clock(void);, we know that the preceding token ( is correct...we're calling a function after all. That must mean that void is mistyped or out of place. Obviously it isn't mistyped. If you drop it, your code works.
What's up with that? Well, unlike some languages, C++ can accept an empty arg list, so long as the function wasn't expecting any arguments. y = clock(); will properly call the function.
[BONUS: If you're trying to call a constructor without any arguments, leave off the parenthesis altogether in the call. It's just one of those weird exceptions.]
So, what about that second error? In general, you should try to fix only the error at the top of the list (unless you know for certain what the other(s) are about). Many times, one error causes other weirder errors to happen as well. To see what I mean, try leaving off a semicolon and check out the errors you get as a result. Fix that error and recompile. If the second error shows up again, THEN you address it.
In regards to your comment to MikeCAT, this is a separate issue, but I'll address it the same anyway. Your clock() function returns clock_t, but you are assigning it to y, which is of type int. It appears that clock_t is based on int, so you should be able to get away with it. However, it may be a good idea to switch y to type clock_t as well, and see if that resolves it.
Beyond that, it may have to do with how you're using clock, though I'm not an expert on that class. If you continue to have problems, create a new question. On StackOverflow, you want to stick to ONE problem in ONE question. :)
(See my comment to your question for some additional tips on surviving and thriving around here.)

C++ insert function pointer into memory

I am trying to overwrite a char and a function pointer on the stack. Based on what I found on this question (How can I store a value at a specific location in the memory?) I was able to figure out how to overwrite the character. My problem now is that I get a compile error saying I am casting it wrong.
void foo(char letter);
void bar(char letter);
void function1()
{
void (*pointer)(char);
pointer = foo;
letter = 'B';
function2();
(*pointer)(letter);
}
void function2()
{
int number; // Used in omitted code
*(char *)(&number + 75) = 'A';
*(void (*)(char)) (&number + 42) = &bar; // This is the line with the error
}
The first injection works but the second one gives me a compile error.
I am running Redhat Linux using a g++ compiler. The error I get from the compiler is:
"cannot convert ‘void (*)(char)’ to ‘void(char)’ in assignment"
If I change that line to *(void(char)) then the compiler says:
"invalid cast to function type ‘void(char)’"
What is the proper syntax for this?
(This is modified code from a school security assignment, I'm not writing malware)
Your goal is to write the address of pass to memory, so why are you casting (&number + 13) to a function pointer? Just do what you did before:
*(long *)(&number + 13) = (long)&pass;
And you won't get a compiler error. As to what will happen when this undefined behavior is invoked, you'll just have to see.
Edit: As #DavidGrayson pointed out, if we deference the right side of the equation, we'd get the contents of the function, not its pointer. So we have to cast it to a POD type, not a pointer.

Why can a const value not be changed in C++ but in C? [duplicate]

This question already has answers here:
how to avoid changing value of const in C
(4 answers)
Closed 8 years ago.
In an interview, I was asked to change constant value in CPP, but I said in CPP it is not possible but in c it is possible using pointer.
Interviewer said that using CPP it is possible and asked me to try but I couldn't and I came back to my room and tried again but what I figured out that I was able to change in C but same code was getting error when compiled as C++.
#include<stdio.h>
main()
{
const int i=5;
int *p;
p=&i;
*p=8;
printf("%d",i);
}
This code is changing the constant value of i in c but when I compile in CPP then
I get an error:
invalid conversion from 'const int*' to 'int*'
Given your error, the actual program must have been the following:
#include<stdio.h>
main()
{
const int i=5;
int *p;
p=&i;
*p=8;
printf("%d",i);
}
This produces a warning with gcc:
warning: assignment discards 'const' qualifier from pointer target type
and an error with g++:
error: invalid conversion from 'const int*' to 'int*'
So, let's change the title of your question to a better one:
Why does C allow conversion from const int * to int *, but C++ doesn't?
The reason why one gives a warning and another gives an error is not because one allows you to discard const qualifier and the other doesn't. It's merely because the C standard leaves such incorrect actions as undefined behavior, while the C++ standard specifically marks it as an error. Either way, doing this is wrong.
You can read this similar question asking why this is possible in C.
What I think interviewer wanted this:
int n = 0;
int const *p = &n;
The expression &n has type “pointer to int.” The declaration for p converts &n to type “pointer to const int,” adding a const qualifier in the process. This is a valid qualification conversion. This conversion in no way invalidates n’s declaration. The program can still use n to alter the int object, even if it can’t use *p for the
same purpose.
*p = 5; // wrong
But
n = 5; // OK
now *p is 5 although it is const type!
Now try to run this code in GCC or g++, it will work:
#include<stdio.h>
int main()
{
int n = 0;
const int *p;
p=&n;
printf("%d\n",*p);
n = 5;
printf("%d\n",*p);
return 0;
}
EDIT: The only way to change the value of const qualified object in C and C++ both is, change the value in the initialization statement:
const int i = 5 ---> const int i = 8
This is why const_cast exists, I believe the interviewer asked this because they have to deal with poorly designed library code they have no control over, however normally you shouldn't have to resort to using it in production.