"Cannot cast from integer to double" error when running an example on Castalia3.3 using Omnet 5.3 - casting

When I run any example of Castalia 3.3 using Omnet5.3 on ubuntu, for example the connectivityMap one, I got this error:
"Cannot evaluate parameter 'packetSpacing': (omnetpp::cIntParImpl)packetSpacing: Cannot cast from type integer to double -- in module (ConnectivityMap) SN.node[1].Application (id=25), at t=0.003536244016s, event #13" .
When I looked at SensorNetwork.ned file, I found parameters that are of double type
parameters:
double field_x = default (30); // the length of the deployment field
double field_y = default (30); // the width of the deployment field
double field_z = default (0); // the height of the deployment field (2-D field by default)
int numNodes; // the number of nodes
string deployment = default ("");
int numPhysicalProcesses = default (1);
string physicalProcessName = default ("CustomizablePhysicalProcess");
string wirelessChannelName = default ("WirelessChannel");
string debugInfoFileName = default ("Castalia-Trace.txt");
Is it a bug problem ? a parameter casting problem with the new version of omnet ?
Help me please, I am not that expert with Omnet yet

No, this is not a bug, it is an intentional change since OMNeT++ 5.3.
The expression:
(double) par("packetSpacing")
results in calling doubleValue(). There is the following description of this method in cPar.h:
Returns value as double. The cPar type must be DOUBLE.
Note: Implicit conversion from INT is intentionally missing.
There are two ways of resolving this issue:
Change the type of packetSpacing form int to double in ConnectivityMap.ned.
or
Force reading the parameter as int by adding intValue(), for example in ConnectivityMap.cc:
packetSpacing = (double) par("packetSpacing").intValue() / 1000.0;

Related

Cast AlignedBox double to AlignedBox int

I'm trying to use Eigen AlignedBox. Specifically, I'm trying to cast a box of double into an int one, by using AlignedBox::cast
AlignedBox<double, 2> aabbox2d = AlignedBox<double, 2>(Vector2d(0.52342, 2.12315), Vector2d(3.87346, 4.72525));
aabbox2d.cast<AlignedBox<int, 2>>();
auto minx = aabbox2d.min().x();
Anyway, when the execution gets to min() I get an assert:
Assertion failed: (((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0), function resize, file /Users/max/Developer/Stage/Workspace/AutoTools3D/dep/libigl/external/eigen/Eigen/src/Core/PlainObjectBase.h, line 312.
Note that this is different from casting a matrix scalar to another one. An object is implied.
Supposedly I'm not doing the cast correctly. Does someone know the right way?
Thank you
Consulting the documentation for AlignedBox::cast shows that the template argument to cast is defined as template<typename NewScalarType> and the return value is *this with scalar type casted to NewScalarType. Thus the cast function does not modify the existing instance of the box, but returns a new one. To make your example work you need to store the returned instance like follows:
AlignedBox<double, 2> aabbox2d = AlignedBox<double, 2>(Vector2d(0.52342, 2.12315), Vector2d(3.87346, 4.72525));
AlignedBox<int, 2> casted = aabbox2d.cast<int>();
const int minx = casted.min().x();
You can play with this here: https://godbolt.org/z/ozE4rzebb
As a side note: as the documentation states, when working with Eigen one should refrain from using auto (probably not a problem in this case though)

How to convert from a string to a double to a double*

I'm learning C++ so this may be a basic question, however, it is a real life problem. I need to convert from a string to a double and then in turn to a double* in the most elegant/modern way possible (>C++98).
The structure is provided by a C based framework (I've simplified the code here as this is the crux of the problem only) and I cannot change the framework as this interfaces with the closed source Metatrader4 trading application (non C based). The programming interface requires a pointer to be passed to the structure.
The strings are being read from a csv file containing a dump which I have taken from the Metatrader4 application. The details of which are beyond this problem. However, the inputs remain strings hence are the origin type.
I appreciate the method used in the framework may be old skool but that's part of life. It doesn't mean that I can't aspire to do something better in my code, hence the reason I asked for elegant/modern solutions. If they don't exist then I'll be forced to use new as someone has already suggested.
I currently have the following none working code:
#include <string>
struct bidAsk
{
double *bid;
double *ask;
};
int main()
{
bidAsk ba;
ba.bid = std::stod("1.100");
ba.ask = &std::stod("1.102");
}
However, both of the above conversion methods fail with conversion errors.
The first line results in an error which states:
E0513 a value of type "double" cannot be assigned to an entity of type "double *"
The second line results in the following error:
E0158 expression must be an lvalue or a function designator
I've also tried static_cast, const_cast, make_unique and (double*) casting with no luck.
Thanks in advance.
The problem is you need some actual values for your pointers to point at. They can't just point at the temporary values returned from your number conversion functions.
struct bidAsk
{
double* bid;
double* ask;
};
int main()
{
bidAsk ba;
// these have to exist somewhere that lives as long as the
// bidAsk object that points to them.
double bid_value = std::stod("1.100");
double ask_value = std::stod("1.102");
ba.bid = &bid_value; // just pointing to the real values above
ba.ask = &ask_value;
}
As others mentioned in the comments, someone has to own the objects, the pointers are pointing at.
extern C {
struct bidAsk
{
double *bid;
double *ask;
};
}
struct BidAskWrapper
{
BidAskWrapper(const std::string& sbid, const std::string& sask)
:bid{std::stod(sbid)}, ask{std::stor(sask)}
{}
//Note: bidAsk valid only till the lifetype of the wrapper
bidAsk make_c_struct() {
return {&bid, &ask};
}
double bid, ask;
};

c++ enum can compare to integer but not assign from integer?

#include <iostream>
enum mode { MODE0=0, MODE1, NUM_MODES};
int main(int args, char ** argv) {
int i = 1;
std::cout << (i == MODE0 ? "true" : "false") << "\n";
std::cout << (i == MODE1 ? "true" : "false") << "\n";
mode test;
test = i; // error
}
Why is it that the comparison of i to enum values works fine, but I get compilation error when assigning mode test variable to an integer value?
enum.cc:10:8: error: invalid conversion from 'int' to 'mode'
[-fpermissive]
My question is specifically about why comparison works and assignment doesn't (not how to fix my code) and it has received a couple of good explanations below.
MODE0, MODE1 and NUM_MODES are guaranteed to be convertible to int (the underlying type of the enum) but the reverse is not true. Not all int can be converted to mode. For example, what is the matching mode for the int 42? Simply put, only the implicit conversion from enum to int is defined, the opposite implicit conversion is not defined.
If you want to convert from int to mode you can preform a static_cast to signal that you are taking the responsibility of ensuring that the value being converted is always legal to convert to mode. Try
test = static_cast<mode>(i);
You can use strongly typed enumerations by adding the class keyword to your enum to prevent any implicit casts and to limit the scope of the enum value names. The definition would look like enum class mode { MODE0 = 0, MODE1, NUM_MODES };. In this case, you must quality the enum value names, for example, you would need to use mode::MODE0 instead of MODE0. This has the advantage that it avoids name collisions.
It's because there is a conversion from an enumerated type to int but there is no conversion in the opposite direction. For the comparison, MODE0 gets promoted to int. For the assignment, i would have to be converted to mode.
Look at it this way. When you do a comparison it doesn't matter if the int is not a valid possible value. If it is not then the comparison will fail and we can go on. Now when we go and try to assign an int to an enum you could assign to it a value that isn't mapped to the enum values. Since we don't want this implicitly happening the conversion is invalid. If you want to tell the compiler that it is okay, you know what you are doing, then you can cast it like:
test = static_cast<mode>(i);

ADTs and values

In Rascal, say I have the code:
value x = 2;
data Exp = con(int n);
Is there a way to call con(x), while x is a value (but actually an integer), without knowing on beforehand what the type of con's first argument is supposed to be (thus without explicitly casting it to an int)?
Why is it possible to call a function, say int something(int n) = n, with an integer defined as a value (e.g. value y = 2) passed into its first argument, while it gives me an error when I try to do the same with user-defined ADTs?
When you call a function in Rascal it actually is doing a pattern match on the arguments. So, if you define int something(int n) = n;, and then call something(x), it matches x with int n, sees that x is actually an int (so it can bind the value to n), and calls the function.
If you were to define value x = 2.5 instead and then call something(x) you would get an error since it cannot bind the value 2.5 to int n. You could overload something with a second definition that takes a real instead, like int something(real r) = toInt(r);, and it would then work. Two items to note here, though: something needs to return the same type in both cases, and you need to import util::Math to get access to toInt.
When you are using a constructor, like con(x), it doesn't do a pattern match for you automatically. The type that you give it has to match the type it expects. If you know that x will always be an int, it would be best to just declare it as such. Another option would be to create a function like Exp makeCon(int n) = con(n); which you could then use as you would like, i.e., Exp myExp = makeCon(x);. It would be best in this case to include a default version of the function, just in case you give it something unexpected, like default Exp makeCon(value x) { throw "Unexpected value <x>"; }, this way if you ever try to create a con with something that isn't an int you will get an error that you can handle, with the ability to create your own error message, add additional error handling versus just showing a message, see the value causing the problem, etc, versus just having the interpreter give an error (which may not give you all the info you want).

C++ Function Overloading Similar Conversions

I'm getting an error which says that two overloads have similar conversions. I tried too many things but none helped.
Here is that piece of code
CString GetInput(int numberOfInput, BOOL clearBuffer = FALSE, UINT timeout = INPUT_TIMEOUT);
CString GetInput(int numberOfInput, string szTerminationPattern, BOOL clearBuffer = FALSE, UINT timeout = INPUT_TIMEOUT);
I can't understand how could string be equal to long?
I'm using Visual C++ 6 (yep I know its old, I'm working on legacy code, so I'm pretty much helpless)
EDIT: The line of code that is triggering the error is
l_szOption = GetInput(13, FALSE, 30 * 10);
The problem is caused by the fact that you are supplying the timeout argument as a signed integer value, which has to be converted to an unsigned one for the first version of the function (since the timeout parameter is declared as UINT).
I.e. the first version of the function requires a conversion for the third argument, while the second version of the function requires a conversion for the second argument (FALSE, which is just 0, to string). In this case neither function is better than the other and overload resolution fails.
Try explicitly giving the third argument the unsigned type
l_szOption = GetInput(13, FALSE, 30U * 10);
or
l_szOption = GetInput(13, FALSE, (UINT) 30 * 10);
(whichever you prefer) and the code should compile as expected.
In other words, the compiler is absolutely right to complain about your code. Your code is indeed broken. The problem in your code has exacty the same nature as in the following simple example
void foo(int i, unsigned j);
void foo(unsigned i, int j);
int main() {
foo(0, 0);
}
This code will also fail to compile for precisely the same reason.
GetInput(13, FALSE, 30 * 10);
My guess is that
FALSE ==> o ==> NULL is getting converted to std::string(NULL)
hence, it cannot determine which method to instantiate.
T0 prove this check this :
GetInput(13, TRUE, 30 * 10); //it works
You are possibly passing that function a second parameter that is neither a BOOL, nor a string, but a type that could be implicitly converted to either.
A character pointer, for example.
To resolve the ambiguity when you call the function either cast the second parameter to BOOL or use string("whatever") if that is indeed std::string.
Consider following case :
BOOL is typedef of int.
GetString(10,'a'); // compiler get confused in resolving the function
whether 'a' is to be converted to BOOL or string ???
When you make function call give proper argument by using static_cast to make desired function to call.
char ch = 'a';
GetString(10,static_cast<BOOL>(ch)); // calls function with 2nd argument as BOOL
GetString(10,static_cast<string>(ch)); //calls function with 2nd argument as string