Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am working with a big MPI project. In one of the files (let's call it as one.c) I have a function like this one:
#include two.h
void foo(){
printf("the value is %f", bar(1));
}
Where in file two.h I have (apart from other function def):
double bar(int);
Finally, in file two.c I have (apart from other stuff):
static double a[2] = {0.0,4.0};
double bar(int temp){
return a[temp];
}
From the above code I should obtain 4.0 but I obtain always 0.0, even if I just put:
return 3.0;
I cannot understand the problem because even if in two.c I do:
double bar(int temp){
printf("temp is %d", temp);
return a[temp];
}
I obtain 1 for temp and a[1] returns also 4.0. So the problem is that is not connecting fine the value between files. Any idea?
NOTE: As I said, it is a BIG MPI project. I am not going to post here all the code because is not reasonable. I just add what I though it was necessary. Of course all is linked, otherwise I would not ask it. I am asking this because it is a very strange thing that I though some strange thing could scape from my knowledge. At the end, I have realised that if I call another double function in two.c, then, if I call again my foo function I obtain the good value but still I do not know why because as I said, bar was being recognised, temp was recognised, and a[temp] had the correct value.
NOTE2: I think that my problem was when doing make mpi. Maybe when saving the files or when I was doing the make, the date was not updated and at the end, files where not built again.
Use #include "two.h".
Otherwise it works for me.
If I make files one.c two.c, and two.h to your specification, add
main.c:
void foo();
imt main(){ foo(); }
compile them:
for c in *.c; do gcc $c -c; done
link them
gcc *.o
and run the result
./a.out
I get:
the value is 4.000000
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to clean up my project, to help expand it further, but there's about 200 lines of variables definitions, calculations and writing into arrays before starting the actual application, and it's an absolute mess.
Is there a way to put all of this into another file, and include these definitions in the file I'd like to use it in (and only that file, to avoid conflicts) ?
I tried creating something like "levelVars.c" and including it in the "level.c" file, but all I get is a bunch of errors.
There's also some custom types and SDL types in here, so..it might cause problems.
The reason I want to do all this is to clean up the file : I'm having trouble navigating between everything with such a massive block of variables.
I also can't reduce their numbers, as I need them all ; every variable is taken in by some functions and used by others, so I can't just reduce their scope and clean up this way. Well, I could maybe cut down ten variables like this, but it won't help much.
The beginning looks like this :
int trackSomething = 0;
int trackSomethingElse = 0;
int yetAnotherCount = 0;
bool active = false;
bool andAnother = false;
bool iThinkYouGotIt = false;
int arr[SIZE_1][SIZE_2];
for(int i = 0 ; i < SIZE1 ; i++)
{
for(int j = 0 ; j < SIZE2 ; j++)
{
arr[i][j] = 0;
}
}
....
while(active)
{
// The actual loop that does something meaningful with all this
}
Don't use the pre-processor to do includes. Use the linker:
$ cat variables.h
extern int d;
$ cat variables.c
int d = 57;
$ cat main.c
#include "variables.h"
#include <stdio.h>
int main(void) { printf("d = %d\n", d); return 0; }
$ gcc -c main.c
$ gcc -c variables.c
$ gcc main.o variables.o
$ ./a.out
d = 57
Your request that the variables only be available to one translation unit is somewhat difficult to enforce, and you really shouldn't try. (Ab)using the pre-processor to include the variable definitions with a #include to force the definitions and their usage to all be in the same translation unit will do it, but your code will be better organized if you don't do that.
I don't think that you'll achieve what you are looking for. You can define a variable in levelVars.c:
int count;
And you want to use it later in another file, don't you? Well, to do that you must reference it again in that new file but saying that the variable "comes from another file" by using extern:
extern int count;
So in the end you will end up with the same 200 variables in your file, only with extern in front of them...
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have not touched C for long really long time. My first language was C. But then we have been taught C++, Java and C# (in college days). Now mostly my work involve Java and groovy. And suddenly I have to do C again. I am not familiar with how industry uses C as I never was in project doing stuff in C.
I started in eclipse CDT, with MinGW on Windows 10. My new program grew big quickly. And my lack of experience was unrevealed to me. When I run, my program used to crash showing Windows dialog saying "MyProgram.exe has stopped working". Now I had no clue whats going wrong. Compilation was clean with no error, but only one warning. Now since from Java world, I was like warnings are not that fatal. So I simply just ignored it (I thats my lack of C experience). And went on debugging found the cause. Realised that the warning was indeed about the cause. Suffered mental frustation of wasting hours in debugging.
So here is code replicating issue in my original code:
1 #include "stdio.h"
2 #include "limits.h"
3
4 typedef struct TempStruct TempStruct;
5
6 struct TempStruct
7 {
8 int a;
9 TempStruct *next;
10 };
11
12 int function1(TempStruct *param)
13 {
14 return param == NULL;
15 }
16
17 int function2(TempStruct **param)
18 {
19 if(function1(param))
20 {
21 return INT_MIN;
22 }
23 *param = (*param)->next;
24 return 0;
25 }
26
27 int main()
28 {
29 TempStruct *tempStructObj = NULL;
30 function2(&tempStructObj);
31 printf("Does not reach here!!!");
32 return 0;
33 }
My C-noob eyes did not see anything wrong in it. Good that I knew how to do debugging. I got following in debugging:
In main() this is done: *tempStructObj = NULL. So, I was expecting function1() to return 1, making function2() returning from line 21.
The issue was that function1() takes TempStruct*. But on line 19, I passed it **param. So inside function1(), param wasnt NULL. So it returned false (0 I guess). So function2() did not returned from line 21. It executed (*param)->next and hence the program crashed.
My questions:
Q1. Shouldn't be such issue be reported as Error's instead of Warnings? Is there any setting which can report such potentially fatal warnings to error?
Q2. Does eclipse logs the reasons of such sudden app crash somewhere? So instead of debugging by stepping through each line, I can simply refer to the report which can possibly specify the line number which caused the crash
Q3. What is industry-standard approach to deal with such mistakes? Of course one will say dont commit the mistake. But I am asking about precautions that are taken to avoid such mistakes or auto detect them. Like above I asked about settings to make eclipse report the issue as fatal one or making crashes to generate report so that stuff can be fixed quickly instead of hours long debuggins. Do you use any better (and possibly involving smaller learning curve) alternative to (eclipse CDT + MinGW + Windows) that will provide more powerful debugging so that I can avoid such errors.
Q4. In point 1 of above diagram, what is that Error: Multiple errors reported.... This stuff occurred occasionally, but not always, say once in 5 debugging sessions. What can be the reason behind such ad hoc behavior?
Q5. In point 3 of above diagram, what is that (0x62ff2c) value of param inside function1()? If I keep signature of function1() correctly as int function1(TempStruct **param) and change inside reference correctly to *param, *param is correctly 0x0 (i.e. NULL):
Edit
This on Ideone works (with C) & prints "Does not reach here!!!". So dont know how it handled (*param)->next.
This on ideone (with C99 Strict) does gives error (not warning).
Q1. No, they are warnings as they are legit C code. It could be possible that you want such code. You can use -Werror on gcc to make warnings to errors. Also add some other flags for turning on more warnings like -Wall -Wpedantic -Wextra -Wshadow -Wconversion -Wno-sign-compare etc. This'd be a bit closer to what you're probably used to when using Java ;-)
Q2. Atleast on Linux you have coredumps, iirc Windows was minidumps. These can be loaded together with the corresponding executable into a debugger. Then you can access backtraces, values etc.
Q3.
Like above I asked about settings to make eclipse report the issue as fatal one or making crashes to generate report so that stuff can be fixed quickly instead of hours long debuggins.
Log yourself. Also there can be macros for easing this.
Do you use any better (and possibly involving smaller learning curve) alternative to (eclipse CDT + MinGW + Windows) that will provide more powerful debugging so that I can avoid such errors.
IDE is pretty irrelevant for C imho. Use Linux with native GCC instead, MinGW is nice but it can be daunting (my experience).
Ofcourse MS VSC++ can also compile C but its just for C++ compatible thus not really specific to one standard.
Q4. Well, multiple errors occured which are listed. If it's difficult to reproduce it might be a problem in your setup, this is exactly the experience I had with MinGW on Windows.
Q5. It's the address -- you have a pointer to a pointer, so the first ("outer") pointer is that address, pointing to another pointer which is NULL.
Or more verbosely:
tempStructObj is a pointer to NULL (ie. an int_ptr which holds the value 0x0.
To function2 you pass another int_ptr which holds the semi-random value/address of the automatic variable int_ptr tempStructObj is stored
Ie. you have such:
Address &tempStructObj: tempStructObj
in the RAM.
When you then call function1, you pass the value of this (not-NULL) pointer. Of course the comparison is thus always false.
You'd need to compare
*param with NULL.
Even more:
If you compile with GCC (on Linux) and use really verbose flags you get:
gcc -std=c99 -Wall -Wpedantic -Wextra -Wshadow -Wconversion -Wno-sign-compare -o main main.c
main.c: In function ‘function2’:
main.c:19:18: warning: passing argument 1 of ‘function1’ from incompatible pointer type [-Wincompatible-pointer-types]
if(function1(param))
^
main.c:12:5: note: expected ‘TempStruct * {aka struct TempStruct *}’ but argument is of type ‘TempStruct ** {aka struct TempStruct **}’
int function1(TempStruct *param)
^
So exactly the problem you had ^^
Also I'd remove the function1 altogether, it's completely unnecessary and just obfuscates the code. Also I'd use a different name for the struct and the typedef, appending the latter with a _t. Also I'd move it into one shorter piece of code.
On a side note: add a \n in the printf()-call.
Edited code:
#include <stdio.h>
#include <limits.h>
typedef struct TempStruct_s {
int a;
struct TempStruct_s *next;
} TempStruct_t;
int function(TempStruct_t **param)
{
if(!*param) {
return INT_MIN;
}
*param = (*param)->next;
return 0;
}
int main()
{
TempStruct_t *tempStructObj = NULL;
function(&tempStructObj);
printf("Does not reach here!!!\n");
return 0;
}
When you
TempStruct *tempStructObj = NULL;
function2(&tempStructObj);
you are sending into function2 the address of your variable tempStructObj (0x62ff2c). When doing
if(function1(param)){
return INT_MIN;
}
you're sending the same address (0x62ff2c). Therefore, param == NULL is false.
Q5: if you use the proper signature, as you suggest, then you check the value that tempStructObj is pointing at, which is what you want, and everything works.
The error you get about not being able to access memory 0x4 is due to your structure and wrong null checking. (*param)->next is expected work on a memory zone with an int and another pointer. However, *param is pointing at address 0x0, so the int is at address 0x0 and the next pointer is at address 0x4, hence the error.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm completely new to programming. I'm actually learning from a Harvard class on iTunes U. When trying to code along side the instructor I've ran into a problem. I can't run my .c program in terminal. I've tried the sudo commands, and I've searched with Google and I can't seem to find an answer, probably because I'm so new to programming. It's probably something I've overlooked or I just don't understand yet.
#include <stdio.h>
int
main(void)
{
printf("temperature in f: ");
float f = GetFloat();
float c=f / 9.0 * (f-32);
Printf("%. if F = %. if c\n", f, c)
I'm using Sublime text editor on a MacBook with Mac OS X Yosemite (10.10.x).
Your compiler should have warn you about some errors:
// string.c
#include <stdio.h>
int main(void) // There must be a return statement
{
printf("temperature in f: ");
float f = GetFloat();
float c = f / 9.0 * (f-32);
printf("%f if F = %f if c\n", f, c); // Missing ';' is the most common syntax error
return 0; // Here is the return
} // Do not forget to close your brackets
When you do:
gcc string.c -o myprogram
It will tell you what is wrong in your program. Once you have fixed all the errors you can run the program with:
./myprogram
Understand that you cannot run a C-file: the .c contains human-readable instructions for the machine. You have to compile it, i.e. translate it into a language that your computer will understand : it is roughly your compiled myprogram (and you do not want to open it to look what it contains, it will burn your eyes :p).
Just adding to the below answer your compiler should throw the below error also:
undefined reference to `Printf'
check case of your printf()
This question already has answers here:
Why do you have to link the math library in C?
(14 answers)
Closed 9 years ago.
I also entered include<math.h> but it still doesnt work. People are saying to enter -Im but im new to this where do I put -Im and how do I fix this.
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int main()
{
float a=0, b=0, c=0, root1=0, root2=0;
printf("Enter the value of a,b and c to determine the roots\n");
scanf("%f%f%f",&a,&b,&c);
root1=(-b+sqrt(b*b-4*a*c))/(2*a);
root1=(-b-sqrt(b*b-4*a*c))/(2*a);
printf("The first roots of the quadratic equation are\nFirst root=%.1f\nSecond root=%.1f",root1,root2);
return 0;
}
You have a copy-paste bug here:
root1=(-b+sqrt(b*b-4*a*c))/(2*a);
root1=(-b-sqrt(b*b-4*a*c))/(2*a);
should be:
root1=(-b+sqrt(b*b-4*a*c))/(2*a);
root2=(-b-sqrt(b*b-4*a*c))/(2*a);
Also you may need to link with the math library, e.g.
$ gcc -Wall foo.c -o foo -lm
Two things: first you copy pasted "root1" twice so you will lose the "plus" value and root2 will be zero. Second, for the benefits of others, the problem is most probably at compile time and the googled answer is there:
http://www.cs.cf.ac.uk/Dave/C/node17.html
And you should test for imaginary values:
if(b*b-4*a*c < 0){
printf("error: complex solution unsupported, see http://en.wikipedia.org/wiki/Square_root\n");
exit(1);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am using Mac OSX 10.8.4 and programming in C. I trying to use openmp and I am compiling with gcc-mp-4.7. I am working in bash. Currently I have an executable (I will call executable1 in the program) which I am trying to run in parallel by using a system call inside of an openmp parallel for loop. The example code is as follows:
my_omp.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
void main() {
int n = 100;
double var1 = 65.4;
char place[100] = "/under/a/rock";
double var2 = 4.5e4;
double var3;
char program[200];
int i;
#pragma omp parallel for private(program,var3)
for (i=0; i<=n; i++) {
var3 = var1*pow(var2,i);
sprintf(program,"./executable1 %.15e %s %.15e %d", var1, place, var2, var3, i);
printf("%s \n", program);
system(program);
}
}
I compile the program using gcc-mp-4.7 -fopenmp my_omp.c, then run the newly compiled executable, (differently named than exectuable1).
What seems to happen is that 8 (which I believe is the number of "cpus" openmp thinks I have) of the print statements will appear in the stdout (terminal) and then it will run only a single call of the executable1, then when it finishes it prints out another of the printf program lines, then runs another executable1 until it finishes the for loop (I know this because executable1 is extremely verbose, and it would be obvious is two where running as numbers printed to stdout would be out of synch and appearing in at multiples).
So it seems maybe that the printf is running in parallel, but for some reason the system() command is not? Does anyone have any ideas?
Thanks for any help you can offer.
UPDATE:
I have gotten this exact code to run properly on a lunix distribution with a different compiler, I will look into finding a better compiler to use in Mac OSX and see if that works.
The system(3) library call in OS X is implemented using a global mutex lock - see the system.c file in the source code of OS X's C library:
#if __DARWIN_UNIX03
pthread_mutex_lock(&__systemfn_mutex);
#endif /* __DARWIN_UNIX03 */
...
#if __DARWIN_UNIX03
pthread_mutex_unlock(&__systemfn_mutex);
#endif /* __DARWIN_UNIX03 */
Therefore when one thread calls into system(3), all other threads have to wait for the first call to finish, resulting in serialised execution.