I call c++/cli method from c# in this method:
bool SetProperty(Element element, Node referencePoint, List<Materializer> materializers, List<ulong> properties)
{
// Loop over STLs
for (int i = 0; i < materializers.Count; i++)
{
Materializer materializer = materializers[i];
PentalTreeNode pentalTreeRoot = pentalTreeDatasets[i].top;
if (materializer.IsPointInside(referencePoint.X, referencePoint.Y, referencePoint.Z, pentalTreeRoot))
{
element.PropertyId = properties[i];
return true;
};
}
return false;
}
C++/cli method is this:
bool IsPointInside(double x, double y, double z, PentalTreeNode ^root)
{
int intersectionCount = 0;
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(_box->IsContainingPoint(x,y,z))
{
intersectionCount=CountIntersects(x,y,z,root);
return (intersectionCount%2!=0);
}
}
What is wrong, because c++/cli method doesn't return always the same result?
How to pin or marshal?
Method in c++/cli(Maybe this not ok?):
int CountIntersects(double x, double y, double z, PentalTreeNode ^root)
{
Math3d::M3d rayPoints[2], intersectionPoint;
rayPoints[0].set(x,y,z);
rayPoints[1].set(x,y,1.0e6);
if(!root)
return 0;
else
{
int special = CountIntersects(x,y,z,root->special);
if (x <= root->xMax && x >= root->xMin && y <= root->yMax && y >= root->yMin)
{
if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
{
return (1 + special);
}
else
return special;
}
else
{
if (y>root->yMax)
{
return (CountIntersects(x,y,z,root->top)+special);
}
else if(y<root->yMin)
{
return (CountIntersects(x,y,z,root->bottom)+special);
}
else if(x<root->xMin)
{
return (CountIntersects(x,y,z,root->left)+special);
}
else if(x>root->xMax)
{
return (CountIntersects(x,y,z,root->right)+special);
}
else
return special;
}
}
}
if( _stlMesh->IsRayIntersectsPoly(root->index, rayPoints, intersectionPoint))
There's one possible flaw in this particular statement, you've never initialized intersectionPoint. C++ lets you get away with this, it doesn't have anything similar to C#'s definite assignment rules. It isn't 100% clear whether that's the real problem, the variable might be passed by reference.
In the Debug build, such an uninitialized variable will have a predictable value. Something you can easily see in the debugger when you switch it to hexadecimal display mode. Fields in this struct or class will contain the value 0xcccccccc, a value that's apt to generate nonsensical results or crash your code with an access violation. In the Release build, the /RTC option isn't turned on and you'll get entirely random values in the variable.
Which corresponds very well with the description of your problem, so high odds that this is indeed the problem. Be sure to use the debugger to find problems like this, you can easily see the value of local variables with the Autos debugger window as you single-step through the code.
You are not calling a C++ method! You are calling a C++/CLI method. And therefore it is normal .NET code and it is always passed correctly. There is no need to pin or marshal anything in C# im this case!
If it returns not the expected values, you should try to find the problem in you C++/CLI project.
Related
if(i<2 && i>10){
//code here will never be reached or what?
}
Just in case of an integer overflow maybe?
Edit: I wrote this not knowing c# is the language used. I've used C++ but I believe that the principle is also valid for c#.
there is no single integer that satisfies the condition
the compiler may well optimize away the body of the if condition (see here for an example on compiler explorer)
however, in the case of i being volatile it is possible that the value of i changes between the i<2 and the i>10 tests. In this case the if body can be reached.
However, though it may be theoretically possible it is highly unlikely that this was the intention.
Here's my example code
#include <iostream>
using std::cout;
void foo(int i)
{
if (i < 2 && i > 10)
{
cout << "The impossible happened in foo\n";
}
}
void bar(volatile int i)
{
if (i < 2 && i > 10)
{
cout << "The impossible happened in bar\n";
}
}
It is indeed possible for some c# (assuming c# because it's tagged... not assuming integer even if it's tagged because the right-hand comparison is still an integer, so it matches the tags! ;-) ) code to go into that if... take:
public class Foo {
public static bool operator> (Foo a, int b) {
return true;
}
public static bool operator< (Foo a, int b) {
return true;
}
}
Then:
Foo i = new Foo();
if(i<2 && i>10){
Console.WriteLine("Pass!");
}
Guess the output? Check it out here
Another way, with no extra classes or operator overloading:
private static bool odd;
public static int i { get { odd = !odd; return odd ? 1 : 11; } }
Check it out
Otherwise, it could also happen if multithreading (if the value of i changes bewtween the comparisons) unless you apply correct locking
please help. I am a begginner at c# but have programed in python before. My problem is that the their is an error which says, Severity 'Program.Sqrt(int)': not all code paths return a value. Please help, i have include a return value and have used an if and else statement.
using System;
namespace helloworld
{
class Program
{
static void Main(string[] args)
{
}
float Sqrt(int x)
{
Console.WriteLine("please enter your number to be square rooted");
string l = Console.ReadLine();
x = Convert.ToInt32(l);
float num = 1;
if (num * num != x)
{
num++;
}
if (num * num == x)
{
return num;
}
else
{
Console.WriteLine("FAILED TO EXECUTE");
}
}
}
}
So this is kinda just C# Basics - well.. programming basics...
If you declare your method as a 'type' of return value other than void, then it expects you to use the keyword 'return' at some stage.
You have created a method called:
float Sqrt(int x)
This indicates that it MUST return a float value.
I can see that in some cases (if statements) you are doing a
return num;
But look carefully. in the other if statements, there is no return statement - so basically, in the else statement it will get stuck.
In order to make sure that your method does not get stuck - you should make sure that it has the possibility of returning either a valid value, or it throws an exception.
if (num * num == x)
{
return num;
}
else
{
throw new Exception("Unable to execute");
}
The most important part of the compiler error you are receiving is that a method with a declared return type must always return a value of that type, or throw an error.
Let's take a look:
float Sqrt(int x)
{
// Your code here
}
What we've just done is declared a method called Sqrt that accepts a single int parameter called x. By using the float type at the beginning of the method, we're stating that this method always returns a float.
In your method body, you must return a float or throw an error. Let's take a look at a simple case.
float Sqrt(int x)
{
if (x > 0)
{
// Calculate square root
return Math.Sqrt(x);
}
else
{
// Ignore imaginary numbers for now, use absolute value
return Math.Sqrt(Math.Abs(x));
}
}
The above code works because both the if and else return a valid value. Your code is failing because your else doesn't return anything; see this simplified example:
float Sqrt(int x)
{
if (x > 0)
{
// Calculate square root
return Math.Sqrt(x);
}
else
{
// Ignore imaginary numbers for now, use absolute value
Console.WriteLine("Don't do that!");
// Note there is no return statement here
}
}
The above example fails, because the else doesn't return anything nor does it throw an exception. Another way to hand this is to throw an appropriate exception:
float Sqrt(int x)
{
if (x > 0)
{
// Calculate square root
return Math.Sqrt(x);
}
else
{
// Ignore imaginary numbers for now, use absolute value
throw new System.ArgumentException("x must be greater than 0");
}
}
The above example them assumes your code knows how to handle an exception. In the if else section, you can perform your logic but you have to return a float value or throw an exception of some kind.
As the error clearly stated, not all code paths return a value, and this will throw an exception.
if (num * num == x)
{
return num; //Okay
}
else
{
Console.WriteLine("FAILED TO EXECUTE");
//returns nothing here
}
To fix this, simply add a return statement after your Console.WriteLine returning what you'd want if the previous condition fails.
.NET compiler expects return statement in all possible scenarios of a function. If code fails that, it returns compilation error.
You could either return some error OR non-possible value in else block. Since in your code, else is not returning any value/exception, it gives an error.
I'm trying to find out if a number is prime or not. But I've got an error of "unreachable code detected", which I think is effecting the error of "not all code paths return a value". The error seems to occur in the for loop at i++. Can anyone help me please?
static void Main(string[] args)
{
Console.WriteLine(isPrime(10));
}
public static bool isPrime(int n)
{
for (int i = 2; i < n; i++)
{
if (n % i == 0)
{
return false;
}
return true;
}
}
"Unreachable code detected" means that some code can never be executed. Consider:
int something()
{
if (true)
return 1;
else
return 2; //Obviously we can never get here
}
"Not all code paths return a value" means that you've defined a method with a return value (like "bool" in your example) and there is some way for the method to execute without returning a value.
Consider:
int something(bool someBool)
{
if (someBool)
return 1;
//if someBool == false, then we're not returning anything. Error!
}
Your code has two problems:
You have return true inside the for loop (outside of any conditional). Because return immediately exits the function (returning control to the caller) the i++ statement of the for loop will never get executed (hence your bug). You likely intended for that to be outside the for loop.
Another problem with that being in the loop is that the loop is not guaranteed to execute. If the n passed was 2 or less, you would skip the loop entirely, and there is no return statement in that case. This isn't allowed (since you always need to return a value from a non-void function) so you get a compiler error.
Below is an example of how to get this return working with a for loop and embedded If condition.
private bool WinOneLevelOne()
{
//For loop to check all the items in the winOne array.
for (int i = 0; i < winOne.Length; i++)
{
//If statement to verify that all the gameobjects in the array are yellow.
if (winOne[i].gameObject.GetComponent<MeshRenderer>().material.color != Color.yellow)
{
//Keeps the boolean at false if all the gameobjects are not yellow.
return false;
}
}
return true;
I'm not quite sure how to ask my question in C# terms, so please bear with the long-winded explanation.
I'm writing a stock trading algorithm. When the algo starts, it checks to see what kind of instrument it is applied to (in this case, either stock or futures), and then depending on the instrument, assigns a value to "double x".
If its a future instrument, then the assignment is a simple, flat value (in this case, "double x = 5;). However, if its a stock, I'd like "x" to be assigned to a value from another object - lets call the object "Algo2" and the value "y". So, in my script the assignment is as follows: "double x = Algo2.y" (note: that's the convention in the editor I'm using). This block of code is run only once when the algorithm begins.
What I'm trying to achieve here is to tell my algorithm to get the latest value of "Algo2.y" whenever "x" is used in a formula such as "EntryValue = Price + x". However, whats happening is that "x" is permanently assigned the value of "Algo2.y" at the start of the program, and since that block is never run again, remains that constant value throughout.
Can anyone help with the syntax so that instead of assigning a value to "x", it simply points to get the latest value of "Algo2.y" whevever it's called?
Thanks!
Make 'x' a property, so that it fetches the value each time you ask for x.
class StockInstrument
{
public double Value //x isn't a good name, I'll use "Value"
{
get
{
if(...) return 5.0;
else return Algo2.y;
}
}
}
Write a function for it:
double getAlgo2YValue()
{
return Algo2.y; // or Algo2.getY(), another function if you can't access it
}
In your main algorithm, now call:
x = getAlgo2YValue();
To update X.
I would use a method to return your latest value
public double GetXValue()
{
if (AlgoType == Algos.Futures)
{
return 5.0;
}
else if (AlgoType == Algos.Stock)
{
return Algo2.y;
}
//else
throw new Exception("unknown algo type");
}
This is quite hard coded, but it could be cleaned up using delegates and encapsulation of the algorithms, but at a low level - this is the idea. Also, some people prefer to use properties for this - Just don't use properties when the get has modifying affects
public double X
{
get
{
if (AlgoType == Algos.Futures)
{
return 5.0;
}
else if (AlgoType == Algos.Stock)
{
return Algo2.y;
}
//else
throw new Exception("unknown algo type");
}
}
May use something like:
double X {
get {
if(isStock())
return Algo2.y;
else
return 5;
}
}
Func<int> getX;
if(isFuture)
getX = () => 5;
else
getX = () => Algo.y;
// using getX() will always return the current value of Algo.y,
// in case it's a stock.
int xval = getX();
Give Algo2 a reference to Algo so that no 'double X' copy is needed. Algo can then dereference the actual value in Algo2 at any time, (thread-safety an issue?).
Value data types, such as int are always going to be copied by value, not as a reference. However, what you can do is architect your solution a little differently, and then it will provide the right value. For example:
public class ValueContainer
{
protected Algo2 _reference = null;
protected double _staticValue = 0;
public double CurrentValue
{
get
{
if(_reference == null)
return _staticValue;
return _reference.y;
}
}
public ValueContainer(Algo2 reference)
{
_reference = reference;
}
public ValueContainer(double value)
{
_staticValue = value;
}
}
Then, you replace your x with the ValueContainer instance wherever needed and use the CurrentValue property to get the value. You create each version with a different constructor then:
ValueContainer container = null;
if(stock)
container = new ValueContainer(5);
else
container = new ValueContainer(Algo2);
What you need is a property wrapper for x to control the value that's returned, based on the instrument type. Here's an example, which will require some significant adaptation for your app.
public class Instrument
{
// an example enum holding types
public InstrumentType Type {get; set;}
// x is not a great name, but following your question's convention...
public double X
{
get
{
if(type == InstrumentType.Stock)
return Algo2.y();
// note that I changed this to be a method rather than a property
// Algo2.y() should be static so it can be called without an instance
else if(type == InstrumentType.Future)
return 5.0;
else
// return some default value here
}
}
}
I am trying to create a Collection with properties and their respective accessors.
Here is my code:
class SongCollection : List<Song>
{
private string playedCount;
private int totalLength;
public string PlayedCount
{
get
{
foreach (Song s in this)
{
if (s.TimesPlayed > 0)
{
return s.ToString();
}
}
}
}
public int TotalLength
{
get
{
foreach (Song s in this)
{
int total = 0;
total += s.LengthInSeconds;
}
return total;
}
}
}
I'm receiving the error at the "get" point. It tells me that not all code paths return a value... What exactly does this mean, and what am I missing?
Firstly, the reason you're getting that message is that if this is empty, then the code within the foreach block (which is where the required return statement is) would never be executed.
However, your TotalLength() function would always return the length of the first Song, as you're declaring your variable, setting its value, then returning it within the foreach block. Instead, you'd need to do something like this:
int totalLength = 0;
foreach(Song s in this)
{
total += s.LengthInSeconds;
}
return totalLength;
Your PlayedCount function suffers from similar issues (if the collection is empty or contains no elements whose TimesPlayed property is greater than 0, then there would be no way for it to return a value), so judging by your comment you could write it this way:
public int PlayedCount()
{
int total = 0;
foreach(Song s in this)
{
if (s.TimesPlayed > 0)
{
total++;
}
}
return total;
}
It means just as it says, not all code paths return a value.
In this case, if your list is empty, then it cannot call return. In a foreach, there must be at least one item for the code to execute. Now, maybe you know that the list will always contain a value, but the compiler can't know that
What would your method return if this did not evaluate?
if (s.TimesPlayed > 0)
{
return s.ToString();
}
try using an else to return an empty string or something
The fact that 'this' could have no songs- in that case the loops will not execute at all and there is no implicit return value in C#.
Furthermore, your getters don't really make sense unless you only ever had one song in the collection. You need something more like this:
public int TotalLength()
{
get
{
int total = 0;
foreach (Song s in this)
{
total += s.LengthInSeconds;
}
return total;
}
}
Finally, without knowing how you keep track of TimesPlayed for each individual song, I wouldn't know how to implement that getter, but I am sure you can figure it out with this much.