private static void convert(int x) {
// assume we've passed in x=640.
final int y = (x + 64 + 127) & (~127);
// as expected, y = 768
final int c = y;
// c is now 320?!
}
Are there any sane explanations for why the above code would produce the values above? This method is called from JNI. The x that is passed in is originally a C++ int type that is static_cast to a jint like so: static_cast<jint>(x);
In the debugger, with the breakpoint set on the y assignment, I see x=640. Stepping one line, I see y=768. Stepping another line and c=320. Using the debugger, I can set the variable c = y and it will correctly assign it 768.
This code is single threaded and runs many times per second and the same result is always observed.
Update from comments below
This problem has now disappeared entirely after a day of debugging it. I'd blame it on cosmic rays if it didn't happen reproducibly for an entire day. Oddest thing I've seen in a very long time.
I'll leave this question open for a while in case someone has some insight on what could possibly cause this.
Step 01: compile it right, see comments under your post.
if needed i with this code it will go:
C# Code:
private void callConvert(object sender, EventArgs e)
{
string myString = Convert.ToString(convert123(640));
textBox1.Text = myString;
}
private static int convert123(int x) {
// assume we've passed in x=640.
int y = (x + 64 + 127) & (~127);
// as expected, y = 768
int c = y;
// c is now 320?!
return (c);
}
but its a c# code
and a tipp for you NEVER call your funktion with a name that is used in the compiler as an standart.
convert is in the most langues used.
(system.convert)
Have you set c to 320 recently? If so, it may have been stored in some memory and the compiler may have reassigned it to what it thought it was and not what it should be. I am, in part, guessing though.
It looks like problem of memory byte size of temporary variables if program is optimized for memory usage. Debugger may not be reliable. I see if the temporary ~127 is store in a byte, then you may reach at the scenario you observed. It all depends on what is ~127 is stored in at run time.
Related
If have the following code I correctly get an warning in eclipse at the else if code :
final int x = 8;
if (x < 10) {
System.out.println(x);
} else if (x < 5) {
System.out.println(x);
}
But I don't get any warning if I replace the line
final int x = 8;
with
final int x = getX();
getX() is defined somewhere.
What is the reason for this?
JVM knows that x always would be less than 10 in compile-time, but if you replace x declaration
final int x = getX();
JVM will know x value to compare only in runtime
Related questions:
Unreachable code error vs. dead code warning in Java under Eclipse?
final int x = 8;
if (x < 10) {
System.out.println(x);
} else if (x < 5) {
System.out.println();
}
Here you declared value as 8.
so if will execute.There is no possibility to execute else.
But in second case first we dont know the value.In runtime only it know.
if you write final int x = 8; the compiler knows for sure that x < 10 and the if branch is always executed, while in the second case it cannot know the value returned by the called function.
At compile time, the compile know that x will always be 8. But if you use a function, it doesn't drill down into that.
A final primitive is a compile time constant, so it can do the unreachable code check when compiling. In this case, the compiler knows x = 8 and can determine the results of the if statement accordingly.
For the getX() approach, it won't do that check at compile time. This means you won't see that warning.
if (8 < 10) {
//Executing code
} else {
if (8 < 5) {
//Alternative code
}
}
I believe this is the essential equivalent of how your code is read by the compiler (someone with more knowledge than I may be able to correct me. Scratch that, I'm certain they can correct me).
With that said if you look at the logical sequence of your steps, you'll see that the compiler has already determined the steps of execution and can determine that the second if is never satisfied. If you use getX() alternatively though the compiler cannot make those assumptions.
If this holds
x<5
Then this also holds
x<10.
Therefore, the second part will never execute even the value in x is unknown.
So, I have to make a random number generator to get numbers ranging from 0 to 400. I'm putting these into an array and then sorting them later on. I just am not sure how to go about doing this. I was given something along the lines of;
public int nextInt(400) //gives me errors
{
random.setSeed(12345L);
for (int i = 0; i < arr.size; i++)
{
val = random.nextInt(400);
a[i] = val;
}
}
I've already called the random class, since the directions indicated that. I just don't know why this is not working. It's giving me errors especially with the first part; class, interface, or enum expected. Could somebody steer me in the right direction please?
Functions in Java (all programming languages) have "variables" in their definition.
You've got:
public int nextInt(400)
Over here, you want your 400 to be a value that is passed to the function.
Think of this as math. I'm sure you've dealt with something like f(x) = 2 * x. Here, x is the variable, and you "evaluate" f(x) with a value for x. Similarly, in programming, we'd have something like :
public int nextInt(int x)
As you see, our function defines x to be of type int. This is necessary in a language like Java because you're telling the compiler that this function will only accept integers for x.
Now that you've done that, you can use x as a variable in the body of your function.
Note that whenever you use a variable, it first has to be defined. A line such as:
int variable;
defines variable as an int.
Your program is missing these for random, val, arr, and a. Note here that arr and a are arrays (and somehow I get the feeling that they should not be two separate variables).
You should really brush up on variables definitions, arrays, and functions before attempting this question. Your best resource would be your textbook, because it'll explain everything in an organized, step-by-step manner. You can also try the many tutorials that are available online. If you have specific questions, you can always come back to StackOverflow and I'm sure you'll find help here.
Good luck!
You need to define this function within a class definition
even you have specified :
public int nextInt(400)
in this line function returns int and in your whole body u didn't have any return statement.
and yes as Kshitij Mehata suggested dont use 400 directly as value use variable over there.
this should be your function:
public int[] nextInt(int x) //gives me errors
{
random.setSeed(12345L);
int[] a=new int[arr.size];
for (int i = 0; i < arr.size; i++)
{
val = random.nextInt(400);
a[i] = val;
}
return a;
}
even there is some issue with arr from where this arr come?
Is there a refactoring tool, either for C or Java that can simplify this type of redundant code. I believe this is called data propagation.
This is essentially what an optimizing compiler would do.
public int foo() {
int a = 3;
int b = 4;
int c = a + b;
int d = c;
System.out.println(c);
return c;
}
into
public int foo() {
int c = 7;
System.out.println(c);
return c;
}
I think it's not a good idea.
It's for example the following code:
long hours = 5;
long timeInMillis = hours * 60 * 1000;
That's much more cleaner and understandable than just:
long timeInMillis = 300000;
I can offer a solution for C. My solution uses the two tools that I described in another answer here (in reverse order).
Here is your program, translated to C:
int foo() {
int a = 3;
int b = 4;
int c = a + b;
int d = c;
printf("%d", c);
return c;
}
Step 1: Constant propagation
$ frama-c -semantic-const-folding t.c -lib-entry -main foo
...
/* Generated by Frama-C */
/*# behavior generated:
assigns \at(\result,Post) \from \nothing; */
extern int ( /* missing proto */ printf)() ;
int foo(void)
{
int a ;
int b ;
int c ;
int d ;
a = 3;
b = 4;
c = 7;
d = 7;
printf("%d",7);
return (c);
}
Step 2: Slicing
$ frama-c -slice-calls printf -slice-return foo -slice-print tt.c -lib-entry -main foo
...
/* Generated by Frama-C */
extern int printf() ;
int foo(void)
{
int c ;
c = 7;
printf("%d",7);
return (c);
}
Yes, the best refactoring tool I've seen people using is thier brain.
The brain seems a remarkably good tool for logically organising code for consumption by other brains. It can also be used to enhance the code with comments, where appropriate, and impart additional meaning with layout and naming.
Compilers are good for optimising the code for consumption by an underlying layer closer to transistors that make up the processor. One of the benefits of a higher generation programming langauge is that it doesen't read like something a machine made.
Apologies if this seems a little glib and unhelpful. I certainly have used variaious tools but I don't recall any tool that handled "data propogation."
Eclipse (and I'm sure NetBeans and IntelliJ) has almost all these refactorings available. I'll give the specifics with Eclipse. Start with:
public int foo() {
int a = 3;
int b = 4;
int c = a + b;
int d = c;
System.out.println(c);
return c;
}
First, d will show as a warning that you have an unread local variable. <CTRL>+1 on that line and select "Remove d and all assignments". Then you have:
public int foo() {
int a = 3;
int b = 4;
int c = a + b;
System.out.println(c);
return c;
}
Next, highlight the a in int c = a + b; and type <CTRL>+<ALT>+I to inline a. Repeat with b and you will have:
public int foo() {
int c = 3 + 4;
System.out.println(c);
return c;
}
Now you're almost there. I don't know of a refactoring to convert 3+4 into 7. It seems like it would be easy for someone to implement, but is probably not a common use-case as others have pointed out that, depending on the domain, 3+4 can be more expressive than 7. You could go further and inline c, giving you:
public int foo() {
System.out.println(3 + 4);
return 3 + 4;
}
But it is impossible to know if this an improvement or a step backwards without knowing the 'real' problem with the original code.
the semantic information of the code may get lost. possible dependencies might break. In short: only the programmer knows which variables are important or may become important, since only the programmer knows the context of the code. I'm afraid you'll have to do the refactoring yourself
Yes, IntelliJ offers this functionality inside of their community edition. Now to address a more serious issue, I am pretty sure you are mixing up compilation with refactoring. When you compile something you take a language higher than machine code and convert it into machine code (essentially). What you want is to remove declarations that are redundant inside the high level language that is your program file, .c,.java,etc . It is quite possible that the compiler has already optimized the less than great code into what you propose, there are tools available to see what it is doing. In terms of refactoring less is typically better, but do not sacrifice maintainability for less lines of code.
One possible approach is to put it into a symbolic math program (like Mathematica or Maple) and have it do the simplification for you. It will do it regardless of whether they are constants or not.
The drawback is that you need to convert the code to a different language. (Though it could be mostly copy and paste if the syntax is similar.) Furthermore, it could be dangerous if you expect certain integer types to overflow at a specific size. Symbolic math programs don't care and will optimize it according to the "math". Same thing goes for floating-point round-off errors.
In your example, if you enter this into Mathematica:
a = 3;
b = 4;
c = a + b;
d = c;
c
Will output this in Mathematica:
7
Of course you can't just copy and paste because it's a different language and different syntax, but it's the best thing I have in mind for your question. I myself use Mathematica to simplify expressions and other math before I throw it into C/C++.
For a more complicated example involving unknowns:
Original C Code:
int a = 3 + x*x;
int b = 4 + y*y;
int c = a + b - 7 + 2*x*y;
int d = c;
Enter this into Mathematica (which is still mostly copy+paste):
a = 3 + x*x;
b = 4 + y*y;
c = a + b - 7 + 2*x*y;
d = c;
FullSimplify[c]
Output:
(x + y)^2
Which transforms back into the following C-code:
d = (x + y)
d = d * d;
This is obviously much more simple than the original code. In general, symbolic programs will even handle non-trivial expressions and will do just as well (or even better) than any compiler internal.
The final drawback is that symbolic math programs like Mathematica or Maple aren't free and are fairly expensive. SAGE is an open-sourced program, but I hear it is not as good as either Mathematica or Maple.
If you're talking about C, you could look at the compiled, optimized assembly code. Then you could refactor your C code to the same structure as the optimized assembly. Like Alfredo said, though, that could lead to more ambiguous code.
Why not compile the code using an optimizing compiler. Then decompile the code. It is just my thought and I have not tried it out.
(In the process of writing my original question, I answered it, but the information might be useful to others, and I thought of a new question)
For instance:
int x;
if (x = 5) { ... }
Creates an error:
Type mismatch: cannot convert from int to boolean. (Because assignment doesn't return a
boolean value)
However,
int x;
if ((x = 5) == 5) {
System.out.println("hi!");
}
will print out "hi!"
And similarly,
String myString = "";
if ((myString = "cheese").equals("cheese")) {
System.out.println(myString);
}
prints out "cheese"
Sadly,
if ((int x = 5) > 2) { ... }
does not work with an in-line declaration. How come? Can I get around this?
Sadly,
I suspect that most Java developers would heartily disagree with that sentiment ...
if ((int x = 5) > 2) { ... }
does not work with an in-line
declaration. How come?
It does not work because a declaration is not a Java expression, and cannot be used in an Java expression.
Why did the Java designers not allow this? I suspect that it is a combination of the following:
Java's syntactic origins are c and C++, and you cannot do this in C or C++ either,
this would make the Java grammar more complicated and the syntax harder to understand,
this would make it easier to write obscure / cryptic programs in Java, which goes against the design goals, and
it is unnecessary, since you can trivially do the same thing in simpler ways. For instance, your example can be rewriten this to make the declaration of x to a separate statement.
Can I get around this?
Not without declaring x in a preceding statement; see above.
(For what it is worth, most Java developers avoid using assignments as expressions. You rarely see code like this:
int x = ...;
...
if ((x = computation()) > 2) {
...
}
Java culture is to favour clear / simple code over clever hacks aimed at expressing something in the smallest number of lines of code.)
Your x only exists within the scope of the assignment, so it's already gone by the time you get to > 2. What is the point of this anyway? Are you trying to write deliberately unreadable code?
Your best way to get around this is to declare x in a scope that will remain valid throughout the if statement. Seriously though, I fail to understand what you're doing here. Why are you creating a variable that is supposed to disappear again immediately?
if ((int x = 5) > 2) { ... }
Yes this will not compile because you can't declare variables inside the condition section of if clause
The > test will work fine, as long as you declare the int outside of the if condition. Perhaps you are simplifying your condition for the sake of brevity, but there is no reason to put your declaration in the condition.
Can I get around this?
Yes, declare your var outside the condition.
Because you didn't declare the int separately as you did in the == test.
jcomeau#intrepid:/tmp$ cat /tmp/test.java
class test {
public static void main(String[] args) {
int x;
if ((x = 5) > 2) System.out.println("OK");
}
}
In Java, for() allows initialization code, but if() doesn't.
You can't declare the variable in condition section. For example
for(int i = 0; j < 9; i++){...}
is completely valid statement. Notice we declare the variable in for but not in a condition clause, now look at this,
for(int i = 0; (int j = 0)<9; i++){...} // Don't try to make logical sense out of it
not allowed.
I have a function that is recursively calling itself, and i want to detect and terminate if goes into an infinite loop, i.e - getting called for the same problem again. What is the easiest way to do that?
EDIT: This is the function, and it will get called recursively with different values of x and y. i want to terminate if in a recursive call, the value of the pair (x,y) is repeated.
int fromPos(int [] arr, int x, int y)
One way is to pass a depth variable from one call to the next, incrementing it each time your function calls itself. Check that depth doesn't grow larger than some particular threshold. Example:
int fromPos(int [] arr, int x, int y)
{
return fromPos(arr, x, y, 0);
}
int fromPos(int [] arr, int x, int y, int depth)
{
assert(depth < 10000);
// Do stuff
if (condition)
return fromPos(arr, x+1, y+1, depth + 1);
else
return 0;
}
If the function is purely functional, i.e. it has no state or side effects, then you could keep a Set of the arguments (edit: seeing your edit, you would keep a Set of pairs of (x,y) ) that it has been called with, and every time just check if the current argument is in the set. That way, you can detect a cycle if you run into it pretty quickly. But if the argument space is big and it takes a long time to get to a repeat, you may run out of your memory before you detect a cycle. In general, of course, you can't do it because this is the halting problem.
You will need to find a work-around, because as you've asked it, there is no general solution. See the Halting problem for more info.
An easy way would be to implement one of the following:
Pass the previous value and the new value to the recursive call and make your first step a check to see if they're the same - this is possibly your recursive case.
Pass a variable to indicate the number of times the function has been called, and arbitrarily limit the number of times it can be called.
You can only detect the most trivial ones using program analysis. The best you can do is to add guards in your particular circumstance and pass a depth level context. It is nearly impossible to detect the general case and differentiate legitimate use of recursive algorithms.
You can either use overloading for a consistent signature (this is the better method), or you can use a static variable:
int someFunc(int foo)
{
static recursionDepth = 0;
recursionDepth++;
if (recursionDepth > 10000)
{
recurisonDepth = 0;
return -1;
}
if (foo < 1000)
someFunc(foo + 3);
recursionDepth = 0;
return foo;
}
John Kugelman's answer with overloading is better beacuse it's thread safe, while static variables are not.
Billy3
Looks like you might be working on a 2D array. If you've got an extra bit to spare in the values of the array, you can use it as a flag. Check it, and terminate the recursion if the flag has been set. Then set it before continuing on.
If you don't have a bit to spare in the values, you can always make it an array of objects instead.
If you want to keep your method signature, you could keep a couple of sets to record old values of x and y.
static Set<Integer> xs;
static Set<Integer> ys;//Initialize this!
static int n=0;//keeps the count function calls.
int fromPos(int [] arr, int x, int y){
int newX= getX(x);
int newY= getY(y);
n++;
if ((!xs.add(Integer.valueOf(newX)) && !ys.add(Integer.valueOf(newY))){
assert(n<threshold); //threshold defined elsewhere.
fromPos(arr,newx,newy);
}
}
IMHO Only loops can go into an infinite loop.
If your method has too many level of recursion the JVM will throw a StackOverflowError. You can trap this error with a try/catch block and do whatever you plan to do when this condition occurs.
A recursive function terminates in case a condition is fulfilled.
Examples:
The result of a function is 0 or is 1
The maximum number of calls is reached
The result is lower/greater than the input value
In your case the condition is ([x0,y0] == [xN,yN]) OR ([x1,y1] == [xN,yN]) OR ([xN-1,yN-1] == [xN,yN])
0, 1, ...N are the indexes of the pairs
Thus you need a container(vector, list, map) to store all previous pairs and compare them to the current pair.
First use mvn findbugs:gui to open a gui which point to the line where this error is present.
I also faced the same problem and I solved it by adding a boolean variable in the loop verification.
Code before ->
for (local = 0; local < heightOfDiv; local = local + 200) { // Line under Error
tileInfo = appender.append(tileInfo).append(local).toString();
while (true) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
}
}
To Solve this problem, I just added a boolean variable and set it to false in the catch block. Check it down
for (local = 0; local < heightOfDiv; local = local + 200) {
tileInfo = appender.append(tileInfo).append(local).toString();
boolean terminationStatus = true;
while (terminationStatus) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
terminationStatus = false;
}
}
This is how i Solved this problem.
Hope this will help. :)