I'm new to C and working with CUDA although I don't think this problem is specific to CUDA - I've been able to transfer data to and from the GPU device without any problems and for testing purposes only working with a single thread.
After a long loop calculating f1 and f2, I have this snippet of code:
float price = 0;
float net = 0;
int numTrades = 0;
for (int j = 1; j < dataCol; j++) {
if (((f1[j] > f2[j]) && (f1[j - 1] < f2[j - 1]) && price == 0)) {
price = data[j];
numTrades++;
}
else if (((f1[j] < f2[j]) && (f1[j - 1] > f2[j - 1]) && price != 0)) {
net += data[j] - price;
price = 0;
numTrades++;
}
}
which as far as I can tell doesn't have any problems, except for the fact that it refuses to compile with an "identifier 'price' is undefined" error coming from the first if statement. This snippet is the first place in my code it's mentioned and I've tried initializing with int, float, double, even boolean but still get the same error.
Anyone have any ideas as to what might be causing this?
Tl;dr if things inexplicably break in one location, look for typos above it ( I was missing a semicolon in the previous line. )
TL;DR - Your code snippet looks ok. Issue is most likely elsewhere in your actual code.
Once possible reason, however, as I see it, is your compiler does not support C99 or above. Variable definition in between a function code (Mixed declaration) is allowed onwards C99. In other versions, it should come at the beginning of the function itself. Then, also, you should have received error in
for(int j=1; j<
as this is also a C99 feature, so my above assumption is not likely to be true.
Please show some more code.
Related
(If this is a duplicate please point me to an answer)
I have two scenarios where a loop is checking a complex expression over and over again (a complex expression would consist of math operations and retrieving data):
for (int i = 0; i < expression; i++) {
// stuff
}
for (int i = 0; i < someNumber; i++) {
if (i == expression) break;
}
I'm wondering if it's more efficient to pre-calculate the expression and check against a known value like so
int known = expression;
for (int i = 0; i < known; i++) {
// stuff
}
for (int i = 0; i < someNumber; i++) {
if (i == known) break;
}
or if it's done by the compiler automatically.
For reference, I'm running the loop ~700 000 000 times and the expression is something like structure->arr[j] % n or sqrt(a * n + b)
Is it even worth it?
If the compiler is able to detect that calculating expression will give the same result every time, it will only do the calculation once.
The tricky part is: "If the compiler is able to ...."
Compilers are very smart and will probably be successful in most cases. But why take the chance?
Just write that extra line to do the calculation before the loop as you did in your second example.
By doing that you send a clear message to the compiler about expression being constant within the loops. Further it may also help your co-workers to easier understand the code.
That said... you yourself must be sure that expression is in fact the same every time. Let's look at your example:
the expression is something like structure->arr[i] % n or sqrt(a * n + b)
Now the first one, i.e. structure->arr[i] % n depends on the loop variable i so it will be a big mistake to move the code outside the loop.
The second (i.e. sqrt(a * n + b)) looks better provided that a n b doesn't change inside the loop.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Is this type of expression in C valid (on all compilers)?
If it is, is this good C?
char cloneString (char clone[], char string[], int Length)
{
if(!Length)
Length=64
;
int i = 0
;
while((clone[i++] = string[i]) != '\0', --Length)
;
clone[i] = '\0';
printf("cloneString = %s\n", clone);
};
Would this be better, worse, indifferent?
char *cloneString (char clone[], char string[], int Length)
{
if(!Length)
Length=STRING_LENGTH
;
char *r = clone
;
while
( //(clone[i++] = string[i]) != '\0'
*clone++ = *string++
, --Length
);
*clone = '\0';
return clone = r
;
printf("cloneString = %s\n", clone);
};
Stackoverflow wants me to add more text to this question!
Okay! I'm concerned about
a.) expressions such as c==(a=b)
b.) performance between indexing vs pointer
Any comments?
Thanks so much.
Yes, it's syntactically valid on all compilers (though semantically valid on none), and no, it isn't considered good C. Most developers will agree that the comma operator is a bad thing, and most developers will generally agree that a single line of code should do only one specific thing. The while loop does a whole four and has undefined behavior:
it increments i;
it assigns string[i] to clone[i++]; (undefined behavior: you should use i only once in a statement that increments/decrements it)
it checks that string[i] isn't 0 (but discards the result of the comparison);
it decrements Length, and terminates the loop if Length == 0 after being decremented.
Not to mention that assuming that Length is 64 if it wasn't provided is a terrible idea and leaves plenty of room for more undefined behavior that can easily be exploited to crash or hack the program.
I see that you wrote it yourself and that you're concerned about performance, and this is apparently the reason you're sticking everything together. Don't. Code made short by squeezing statements together isn't faster than code longer because the statements haven't been squeezed together. It still does the same number of things. In your case, you're introducing bugs by squeezing things together.
The code has Undefined Behavior:
The expression
(clone[i++] = string[i])
both modifies and accesses the object i from two different subexpressions in an unsequenced way, which is not allowed. A compiler might use the old value of i in string[i], or might use the new value of i, or might do something entirely different and unexpected.
Simple answer no.
Why return char and the function has no return statement?
Why 64?
I assume that the two arrays are of length Length - Add documentation to say this.
Why the ; on a new line and not after the statement?
...
Ok so I decided to evolve my comments into an actual answer. Although this doesn’t address the specific piece of code in your question, it answers the underlying issue and I think you will find it illuminating as you can use this — let’s call it guide — on your general programming.
What I advocate, especially if you are just learning programming is to focus on readability instead of small gimmicks that you think or was told that improve speed / performance.
Let’s take a simple example. The idiomatic way to iterate through a vector in C (not in C++) is using indexing:
int i;
for (i = 0; i < size; ++i) {
v[i] = /* code */;
}
I was told when I started programming that v[i] is actually computed as *(v + i) so in generated assembler this is broken down (please note that this discussion is simplified):
multiply i with sizeof(int)
add that result to the address of v
access the element at this computed address
So basically you have 3 operations.
Let’s compare this with accessing via pointers:
int *p;
for (p = v; p != v + size; ++p) {
*p = /*..*/;
}
This has the advantage that *p actually expands to just one instruction:
access the element at the address p.
2 extra instructions don’t seam much but if your program spends most of it’s time in this loop (either extremely large size or multiple calls to (the functions containing this) loop) you realise that the second version makes your program almost 3 times faster. That is a lot. So if you are like me when I started, you will choose the second variant. Don’t!
So the first version has readability (you explicitly describe that you access the i-th element of vector v), the second one uses a gimmick in detriment of readability (you say that you access a memory location). Now this might not be the best example for unreadable code, but the principle is valid.
So why do I tell you to use the first version: until you have a firm grasp on concepts like cache, branching, induction variables (and a lot more) and how they apply in real world compilers and programs performance, you should stay clear of these gimmicks and rely on the compiler to do the optimizations. They are very smart and will generate the same code for both variants (with optimization enabled of course). So the second variant actually differs just by readability and is identical performance-wise with the first.
Another example:
const char * str = "Some string"
int i;
// variant 1:
for (i = 0; i < strlen(str); ++i) {
// code
}
// variant 2:
int l = strlen(str);
for (i = 0; i < l; ++i) {
// code
}
The natural way would be to write the first variant. You might think that the second improves performance because you call the function strlen on each iteration of the loop. And you know that getting the length of a string means iterating through all the string until you reach the end. So basically a call to strlen means adding an inner loop. Ouch that has to slow the program down. Not necessarily: the compiler can optimize the call out because it always produces the same result. Actually you can do harm as you introduce a new variable which will have to be assigned a different register from a very limited registry pool (a little extreme example, but nevertheless a point is to be made here).
Don’t spend your energy on things like this until much later.
Let me show you something else that will illustrate further more that any assumptions that you make about performance will be most likely be false and misleading (I am not trying to tell you that you are a bad programmer — far from it — just that as you learn, you should invest your energy in something else than performance):
Let’s multiply two matrices:
for (k = 0; k < n; ++k) {
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
r[i][j] += a[i][k] * b[k][j];
}
}
}
versus
for (k = 0; k < n; ++k) {
for (j = 0; j < n; ++j) {
for (i = 0; i < n; ++i) {
r[i][j] += a[i][k] * b[k][j];
}
}
}
The only difference between the two is the order the operations get executed. They are the exact same operations (number, kind and operands), just in a different order. The result is equivalent (addition is commutative) so on paper they should take the EXACT amount of time to execute. In practice, even with optimizations enable (some very smart compilers can however reorder the loops) the second example can be up to 2-3 times slower than the first. And even the first variant is still a long long way from being optimal (in regards to speed).
So basic point: worry about UB as the other answers show you, don’t worry about performance at this stage.
The second block of code is better.
The line
printf("cloneString = %s\n", clone);
there will never get executed since there a return statement before that.
To make your code a bit more readable, change
while
(
*clone++ = *string++
, --Length
);
to
while ( Length > 0 )
{
*clone++ = *string++;
--Length;
}
This is probably a better approach to your problem:
#include <stdio.h>
#include <string.h>
void cloneString(char *clone, char *string)
{
for (int i = 0; i != strlen(string); i++)
clone[i] = string[i];
printf("Clone string: %s\n", clone);
}
That been said, there's already a standard function to to that:
strncpy(const char *dest, const char *source, int n)
dest is the destination string, and source is the string that must be copied. This function will copy a maximum of n characters.
So, your code will be:
#include <stdio.h>
#include <string.h>
void cloneString(char *clone, char *string)
{
strncpy(clone, string, strlen(string));
printf("Clone string: %s\n", clone);
}
I am following the book Let us C and the following code has been shown as being perfectly correct:
for ( i < 4 ; j = 5 ; j = 0 )
printf ( "%d", i ) ;
But in the Turbo C it gives 3 warnings:
Code has no effect. Possibly incorrect assignment. 'j' is assigned a
value that is never used.
If the book is making the point that this code is allowed by the C standard, then it is correct. This code does not violate any rule of the C standard, provided that i and j have previously been declared correctly (and printf too, by including #include <stdio.h>).
However, nobody would actually write code like this, because it is not useful. That is why the compiler is issuing a warning, because the code is technically allowed but is probably not what a programmer would intend.
If the book is claiming that this code is useful in some way, then it is probably a typographical error. It is certainly wrong. If the book has more than a few errors like this, you should discard it.
I don't know what your book want to teach you with this example, but AFAIK a for loop should always be in the form
for ( init; check; next ) {
/* do something */
}
where init initialize what you're going to use, check check if it should stop or continue and next perform some kind of action. It is the same as
init;
while ( check ) {
/* do something */
next;
}
Therefore you are getting the warning because:
Code has no effect is referred to i < 4. As you can see in the while form, this comparison isn't used in any way, therefore it has no effect.
Possibly incorrect assignment. is refereed to j = 5 cause you're making a check of an assignment witch will always evaluate to the value assigned (in this case 5)
'j' is assigned a value that is never used as it says, 'j' is never used, as you print the 'i' in this example.
Probably what the book wants to do is for ( i = 5; i < 5; i++ ).
And probably what you need to do is using a better book.
It is valid C code but it's pretty much meaningless. This will not initialize the loop properly and trigger an infinite loop. Loops look something like
for (i = 0; i < 10; i++)
The first statement is the initializer, the second stipulates the end case, and the last is the increment. I would get rid of that book
Check this out.
int i=0;
for(i=0;i<5;i++)
{
printf("%d",i);
}
This is a correct but infinite loop,
the correct way to instantiate a for loop is
int i ;
for(i = 0; i< [variable or number];i++){
printf("%d",i);
}
the code you wrote is meaningless and you can't do anything with that code, actually it print the value of i infinite time because it never change.
The only thing we know about i is less then 4. Probably the output is always the same number.
For years, I've gotten in to the habit of not using the value of a for loop iterator after the loop exits. I could have sworn that I did this, because it used to produce a compiler warning, but after I was challenged in a recent code review, I was proven wrong.
For example, I always did this (NOTE: our code standards prohibit the use of the "break" keyword):
int i, result;
bool done = false;
for (i=0; i<10 && !done; i++) {
if (some_condition) {
result = i;
done = true;
}
}
// Value of i may be undefined here
Now, obviously the result variable could be removed, if I can rely on the value of i. I thought that because of compiler optimization, you could not rely on the value of the loop iterator. Am I just remembering a phantom teaching? Or is this the standard (specifically regarding GNU C)?
There is nothing wrong in C89, C99, or C11 to access the iteration variable after the for statement.
int i;
for (i = 0; i < 10; i++) {
/* Some code */
}
printf("%d\n", i); // No magic, the value is 10
From C99, you can use also a declaration as the first clause of the for statement, and in that case of course the declared variable cannot be used after the for statement.
Different languages have different rules. In Pascal, the compiler is allowed to optimize away storing the loop index after the final increment, so it might be the first loop-terminating value or it might be the last valid value.
There are plenty of usage cases where the for loop is used for nothing else but advancing the iterator. This can be seen in some implementations of strlen (though admittedly there are other ways to do strlen), and other sorts of functions whose goal it is to find a certain limit:
/*find the index of the first element which is odd*/
for (ii = 0; ii < nelem && arry[ii] % 2 == 0; ii++);
As mentioned, the point of confusion may come from constructs where the iterator itself is defined within the for statement.
In general for statements are very very powerful, and it's unfortunate that they're usually never utilized to their full potential.
For example, a different version of the same loop can be written as follows (though it wouldn't demonstrate the safety of using the iterator):
#include <stdio.h>
int main(void)
{
int cur, ii = 0, nelem, arry [] = { 1, 2, 4, 6, 8, 8, 3, 42, 45, 67 };
int sum = 0;
nelem = sizeof(arry) / sizeof(int);
/* Look mom! no curly braces! */
for (
ii = 0;
ii < nelem && ((cur = arry[ii]) %2 == 0 ||
((printf("Found odd number: %d\n", cur)||1)));
ii++, sum += cur
);
printf("Sum of all numbers is %d\n", sum);
return 0;
}
In this particular case, it seems like a lot of work for this specific problem, but it can be very handy for some things.
Even though the value of that for loop's control variable is well defined, you might have been told to avoid using the for loop's control variable after the for loop because of the way scoping of that variable is handled, and especially because the handling has changed of the history of C++ (I know this question is tagged "C", but I think the rationale for avoiding using for loop control variable after the loop may have origins in this C++ history).
For example, consider the following code:
int more_work_to_do(void)
{
return 1;
}
int some_condition(void)
{
return 1;
}
int foo()
{
int i = 100;
while (more_work_to_do()) {
int done = 0;
for (int i = 0; i < 10 && !done; i++) {
if (some_condition()) {
done = 1;
}
}
if (done) return i; // which `i`?
}
return 1;
}
Under some old rules of scoping for the i declared in the for loop, the value returned on the statement marked with the comment "which i" would be determined by the for loop (VC++ 6 uses these rules). Under the newer, standard rules for scoping that variable, the value returned will be the i declared at the start of the function.
While I can't possibly know how your habit came to be, I can tell you how my habit to do the same did. It was by seeing code like this:
for (i=0u; (i<someLimit) && (found != TRUE); i++)
{
if (someCondition) found = TRUE;
}
foundIndex = i-1;
Basically, code like this is written when the break keyword is disallowed by some coding rules, e.g. based on MISRA. If you don't break out of the loop though, the loop will usually leave you with an "i" which is off by one from what you care for.
Sometimes, you can even find this:
for (i=0u; (i<someLimit) && (found != TRUE); i++)
{
if (someCondition) found = TRUE;
}
foundIndex = i;
This is just semantically wrong and can be found when the "forbid break keyword rule" is introduced into an existing code base which is not sufficiently covered by unit tests. May sound surprising, but it's all out there...
I might've gone crazy here, but I keep recompiling the exact same code, and get different answers. I'm not using any random values at all. I am strictly staying to floats and 1D arrays (I want to port this to CUDA eventually).
Is it possible on the compiler side that my same code is being redone in a way that makes it not work at all?
I run the .exe by just clicking on it and it runs fine, but when I click "compile and run" (Dev C++ 4.9.9.2) none of my images come out right. ...although sometimes they do.
...any insight on how I fix this? If I can provide any more help please tell me.
Much Appreciated.
Edit:
Here's the block of code that if I comment it out, everything runs sort of right. (Its completely deterministic if I comment this block out)
-this is a electromagnetic simulator, if that helps at all:
//***********************************************************************
// Update HZ in PML regions (hzx,hzy)
//***********************************************************************
boundaryIndex = 0;
for (regionIndex = 1; regionIndex < NUMBEROFREGIONS; regionIndex++) {
xStart = regionData[regionIndex].xStart;
xStop = regionData[regionIndex].xStop ;
yStart = regionData[regionIndex].yStart;
yStop = regionData[regionIndex].yStop ;
for (i = xStart; i < xStop; i++) {
for (j = yStart; j < yStop; j++) {
hzx = hz[i*xSize+j] - hzy[boundaryIndex]; // extract hzx
hzx = dahz[i*xSize+j] * hzx + dbhz[i*xSize+j] * ( ey[i*(xSize+1)+j] - ey[(i+1)*(xSize+1)+j] ); // dahz,dbhz holds dahzx,dbhzx
hzy[boundaryIndex] = dahzy[boundaryIndex] * hzy[boundaryIndex] + dbhzy[boundaryIndex] * ( ex[i*ySize+j+1] - ex[i*ySize+j] );
hz[i*xSize+j] = hzx + hzy[boundaryIndex]; // update hz
boundaryIndex++;
} //jForLoop /
} //iForLoop /
} //
where, NUMBEROFREGIONS is constant (8), Xsize is defined at compile time (128 here).
Well some code examples would help! But this is a classic symptom of un-initialized variables.
You are not setting some important variables (indexes to 0, switches to True etc.) so your program picks up whichever values are hanging around in memory each time you run.
As these are effectively random values you get different results each time.
Is there an indexing error with your simulated two-dimensional array? Is ey supposed to be xSize or xSize+1 wide?
dahz[i*xSize+j] * hzx +
dbhz[i*xSize+j] * ( ey[i*(xSize+1)+j] -
ey[(i+1)*(xSize+1)+j] );
Your index treats 2D array ey as being xSize+1 wide. The code for array ex treats it as being ySize wide.
dbhzy[boundaryIndex] * ( ex[i*ySize+j+1] - ex[i*ySize+j] );
You are potentially invoking undefined behaviour. There are a number of things that are undefined by the C language standard. Some of these cases can be caught by the compiler and you may be issued a diagnostic, others are harder for the compiler to catch. Here is just a few things that have undefined behaviour:
Trying to use the value of an uninitialised variable:
int i;
printf("%d\n", i); // could be anything!
An object is modified more than once between sequence points:
int i = 4;
i = (i += ++i); // Woah, Nelly!
Reading or writing past the end of an allocated memory block:
int *ints = malloc(100 * sizeof (int));
ints[200] = 0; // Oops...
Using printf et. al but providing the wrong format specifiers:
int i = 4;
printf("%llu\n", i);
Converting a value to a signed integer type but the type cannot represent the value (some say this is implementation defined and the C language specification seems ambiguous):
signed short i;
i = 100.0 * 100.0 * 100.0 * 100.0; // probably won't fit
Edit:
Answered before OP provided code.
Are you compiling it in debug mode or release mode? Each one of these have different way how they initialize the heap and memory.
As everybody said without some code of what is wrong we can't help you a lot.
My best gest from what you just explained is that your creating pointers on non allocated memory.
something like this
APointer *aFunction(){
YourData yd = something;//local variable creation
return yd;
}
main(){
APointer *p = aFunction();
}
Here p is a pointer to something that was a local varaible in aFunction and got destroyed as soon as it left the function, this will sometime by PURE LUCK still point to the right data that hasn't been written over, but this memory space will eventual be changed and your pointer will be reading something different completly random.