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 facing a very strange problem.
- I have an if condition:
if((IN_SYNC == sync_flag) || (cycle_number == spi_slot_number))
Before the condition, the variable "spi_slot_number" is '7' and after the if condition it was turned to '0' (which is the value of "cycle_number") !!!
Does any one knows how can such thing happen ?!
Important notes:
1- My code is in C language.
2- I checked the stack before and after the condition to make sure no stack corruption happening.
3- My program is one thread program, so no interrupts or other threads can interrupt.
4- If I commented the if condition , every thing goes fine.
5- I don't know how to generate the assembly code ...
As said by others, you haven't shared enough code to actually identify where your problem is. One thought that occurred to me however is the IN_SYNC identifier. It's a standard coding convention to put macros in all caps, and if it is a macro, it's possible that it's doing the dirty deed. Check for definition of IN_SYNC.
One other thing -- your if test has two tests, separated by an || operator. Try breaking the two tests apart to see which one is causing your side effect. Something like this:
printf("%d \n", spi_slot_number);
if (IN_SYNC == sync_flag) {
/* do nothing */
}
printf("after IN_SYNC test %d \n", spi_slot_number);
if (cycle_number == spi_slot_number) {
/* do nothing */
}
printf("after cycle_number test %d \n", spi_slot_number);
What happens if you do comparision on temporal copy of spi_slot_number? Does it work as expected?
void GetData(slot_id_T spi_slot_number, uint8_t* data_received,
uint16_t data_length, uint8_t data_is_valid_flag)
{
uint8_t cycle_number;
slot_id_T copy = spi_slot_number; // <- ADDED
cycle_number = GetCycleNumber() + 1;
if(cycle_number > LAST_CYCLE)
{
cycle_number = 0;
}
printf("%d \n", spi_slot_number);
if((IN_SYNC == sync_flag) || (cycle_number == copy)) // <- CHANGE
{
printf("%d \n", spi_slot_number);
switch(data_is_valid_flag)
{
case DATA_IS_VALID:
SendData(spi_slot_number, p_buffer, data_length);
break;
case DATA_IS_NOT_VALID:
IndicateDataNotValid(spi_slot_number, p_buffer, data_length);
break;
default:
/* Do Nothing */
break;
}
}
}
Related
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 5 years ago.
Improve this question
So, I have some class work that I cannot solve. I could get the code to work partially but now it is just useless. It either freezes (doesn't complete running) or it will give me several inf in the first row.
#include <stdio.h>
#include <math.h>
int main()
{
double a[10][11]={
{3.55618, 5.87317, 7.84934, 5.6951, 3.84642, 9.15038, -1.68539, 5.03067, 7.63384, -1.75626, -1.92193},
{-4.82893, 8.38177, -0.301221, 5.10182, -4.1169,-6.09145, -3.95675, -2.33365, 1.3969, 6.54555, -2.35262},
{-7.64196, 5.66605, 3.20481, 1.55619, -1.19814, 9.79288, 5.35547, 5.86109, 4.95544, -9.35749, 2.27709},
{-2.95914, -9.16958, 7.3216, 2.39876, -8.1302, -7.55135, -2.37718, 7.29694, 5.9867, 8.5401, -2.67493},
{-8.42043, -0.369407, -5.4102, -8.00545, 9.22153, 3.96454, 5.38499, 0.438365, 0.419677, 4.17166, 1.84756},
{6.02952, 4.57728, 5.46424, 3.52915, -1.01135, -3.74686, 8.14264, -8.86961, -2.88114, 1.29821, 4.154126},
{0.519819, -6.16655, 1.13216, 2.75811, -1.05975, 4.20286, -3.45764, 0.763558, -0.281287, -9.76168, -.93387},
{5.15737, -9.67481, 9.29904, -3.93334, 9.12785, -4.25208, -6.1652, 2.5375, 0.139195, 2.00106, -1.28356},
{-4.30784, 1.40711, -6.97966, -9.29715, 5.17234, 2.42634, 1.88818, -2.05526, -3.7679, 3.3708, -3.46841},
{-4.65418, 7.18118, 6.51338, 3.13249, 0.188456, -16.85599, 7.21435, -2.93417, 1.06061, 1.10807, -2.61529}};
int i, j, k, l;
double b[10][11];
i=0;
while(i<10)
{
j=0;
l=i;
while(l<10)
{
j=0;
l++;
while(j<11)
{
This code below works fine. When used on its own, it will turn all the diagonal values into 1.
b[i][j]=a[i][j]/a[i][i];
This code used below to work partially, setting the first column equal to 0, but now it is useless. I tried to manipulate it into getting rid of all values by having that 0 be a k, with k++ within the while code, but it would return either a segmentation code if I placed it by the i++; or a bus error is placed in front of the j=0;, and it would just freeze the program if I placed the i in the 0. Now it is useless that I restored it to default
b[l][j]=a[l][j]-b[i][j]*a[l][0];
j++;
}
}
i++;
}
j=0;
i=0;
while(i<10)
{
while(j<11)
{
printf("%lf\t", b[i][j]);
j++;
}
printf("\n");
i++;
j=0;
}
return 0;
}
How do I go about solving all these issues within my C program?
Not 100% sure what your code is up to, but I see at least 1 place where I believe that you are reading off the end of your arrays:
while(l<10)
{
j=0;
l++;
...
b[l][j]=a[l][j]-b[i][j]*a[l][0];
Because you are incrementing after you check for max size, you have 1 iteration where you are probably reading passed the max size of the array.
To check, put some prints on your indexes in your code where you do your assignments or assert them or something and I think you will find the source of your woes.
Also, PLEASE use constants for your sizes instead of the magic numbers all over the place. You will thank me later when trying to do a calculation of a matrix of a different size.
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
so in this function of mine, it is spitting out this warning: "carboard.c:79:1: warning: control reaches end of non-void function [-Wreturn-type]". Program runs fine, but i just want it to compile cleanly.
here is the code of the function:
int loadMainMenu()
{
char choice[LINE + EXTRA_SPACES];
Boolean menu = TRUE;
printf("\nWelcome to Car Board\n");
printf("--------------------\n");
printf("1. Play Game\n");
printf("2. Show Student's Information\n");
printf("3. Quit\n");
printf("\n");
printf("Please Enter Your Choice:\n");
do
{
int input;
fgets(choice, LINE + EXTRA_SPACES, stdin);
if (choice[strlen(choice) - 1] != '\n')
{
printf("BUFFER OVERFLOW!\n\n");
readRestOfLine();
}
choice[strlen(choice) - 1] = 0;
input = atoi(choice);
switch(input)
{
case 1: playGame();
break;
case 2: showStudentInformation();
loadMainMenu();
break;
case 3:
printf("Bye bye! \n");
return EXIT_SUCCESS;
break;
default: printf("Invalid input\n");
loadMainMenu();
break;
}
}while(menu);
}
You need to have a return statement in your code. Since your function is returning an integer you must have something likek return x; where x is an integer or you can declare function void.
The compiler is not that smart to figure out the do ... while never terminates.
To fix this, first ensure the loop cannot end by making it guaranted infinite using a constant:
do {
} while ( true );
If that doesn't work, try
while ( true ) {
...
}
The compiler might require a specific pattern ( for ( ; ; ) might also be worth a try; it is also a matter of personal preference).
If that still does not work, just return 0; after the loop above. That might be optimised away, so no extra code at best. At worst, you have to live with some dangling code.
An alternative would be to temporarily disable the warning using a pragma. That should really only be the last ressort.
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 7 years ago.
Improve this question
In my code I have a if statement, which looks like:
if(someFunction1(a) || someFunction2(b->b1,c) || *d == null || somefunction3(e) > f * g || !e->e1 || ...){
return 0;
} else {
do_something;
}
In my code with real variable and function names are conditions nearly in three lines and it looks very overlook. So I decided to rewrite it into form:
if(someFunction1(a)){
return 0;
} else if(someFunction2(b->b1,c)){
return 0;
} else if(*d == null){
return 0;
} else if(somefunction3(e) > f * g){
return 0;
} else if(!e->e1){
return 0;
} else if(...){
return 0;
} else{
do_something;
}
Is there any argument why I should not do it?
From a purely semantic-syntactical point of view there's no effective difference between them. But if readability is your concern, why don't you use the "datenwolf" formatting style – I came to develop that style over the course of my past 5 projects or so:
if( someFunction1(a)
|| someFunction2(b->b1,c)
|| *d == null
|| somefunction3(e) > f * g
|| !e->e1
|| ...
){
return 0;
} else {
do_something;
}
Do you see how beautiful everything lines up? It really looks like a tube the program is falling down through until it hits a met condition. And if you have && it looks like a chain of operations that must not be broken.
As you're asking because of readability you may want to rearrange the long conditional into predicate variables that say why zero must get returned.
bool unnecessary = someFunction1(a) || someFunction2(b->b1,c);
bool beyondTolerance = somefunction3(e) > f * g;
bool invalidInput = *d == nullptr || !e->e1;
if (unnecessary || beyondTolerance || invalidInput)
return 0;
else
...
This is Martin Fowler's Decompose Conditional refactoring.
Option 1:
Terseness
One exit point to avoid redundancy of return statement.
Option 2:
Exact failure point can be diagnosed easily i.e logs can be added to each branch to detect the failure.
I don't think there is any other problem in this code other than the redundancy involved. If at all you have to make change to the return statement, you have to change it at 6 places,according to your implementation.
But that redundancy does not occur in the first implementation.
Both are similar otherwise.
First of all, you can't answer this question without providing some rationale, or the answer will become completely subjective. I would be wary of people answering "do like this, because I like this best", with no rationale provided.
Looking at the code, it is obviously a number of error checks done inside a function. In a real code example, all such error handling usually requires plenty of comments, to describe each individual error condition, as functions with extensive error handling tend to be complex.
Given that, it is not a good idea to write the code as one statement at all, because if you have to squeeze in comments in the middle of the statement, the code will become a mess.
With the above rationale, the best way to write such is perhaps:
/* comments here */
if(someFunction1(a)){
return 0;
}
/* comments here */
if(someFunction2(b->b1,c)){
return 0;
}
...
/* if we got here, then there are no errors */
do_something();
This also have the advantage of being maintainable, should you need to execute code in between the error checks. Or if you wish to split some of the more complex expressions into several lines for readability.
Even though there are plenty of cases where multiple return statements have the potential to create messy code, this is not one of them. In for this case, multiple return statements actually improve readability/maintainability. You shouldn't dogmatically avoid multiple return statements just because some coding standard tells you to do so.
You can do it the following way
int not_valid = someFunction1(a) ||
someFunction2(b->b1,c) ||
*d == null ||
somefunction3(e) > f * g ||
!e->e1 || ...;
if ( !not_valid )
{
do_something;
}
return !not_valid;
Instead of not_valid you can select a more appropriate name.:)
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 8 years ago.
Improve this question
Why I am getting runtime error (SIGSEGV) on the following code:
#include<stdio.h>
#include<string.h>
int main()
{
int t_line,count[10000],i;
scanf("%d",&t_line);
for(i=1;i<=t_line;i++)
{
fflush(stdin);
gets(t);
count[i]=(int)t[0]+(int)t[1]+(int)t[2];
}
for(i=1;i<=t_line;i++)
printf("%d\n",count[i]);
return 0;
}
I have also tried to solve this problem by initialized all the elements of array.
I am wondering how the code compiled, without declaration of the variable t. But, still the only missing elemnt was: char t[your choice of size];. Apart from that
#include<stdio.h>
//#include<string.h> No need of this header,a s you are not using any string functions
int main()
{
int t_line,count[10000],i;
char t[64];//you need to declare the variable before using it
scanf("%d",&t_line);
//Its safer if you check this
if(t_line >= 10000)//if you use 0 and < t_line in for loop below then change the condition to: if(t_line > 10000)
{
printf("ERROR: Limit exceeded. Not enough memory.\n");
return 1;//or you could use exit(1); and #include <stdlib.h>
}
for(i=1;i<=t_line;i++)//suggested: for(i=0;i<t_line;i++)
{
//fflush(stdin);
//gets(t);
char *rc = fgets(t, sizeof(t), stdin);
if(rc != NULL)
{ t[strlen(t) - 1] = '\0';\\because fgets gets the \n into the string too. This line makes fgets similar to gets, improving safety from overflow.
}
else
{
// handle fgets failed error
}
count[i]=(int)t[0]+(int)t[1]+(int)t[2];
}
for(i=1;i<=t_line;i++)//suggested: for(i=0;i<t_line;i++)
printf("%d\n",count[i]);
return 0;
}
Find the solution and suggested changes inline as code comments.
In C, its better to use indexes starting from 0, unless there is a specific requirement to use other values.
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 5 years ago.
Improve this question
I'd love some references, or tips, possibly an e-book or two. I'm not looking to write a compiler, just looking for a tutorial I could follow along and modify as I go. Thank you for being understanding!
BTW: It must be C.
Any more replies would be appreciated.
A great way to get started writing an interpreter is to write a simple machine simulator. Here's a simple language you can write an interpreter for:
The language has a stack and 6 instructions:
push <num> # push a number on to the stack
pop # pop off the first number on the stack
add # pop off the top 2 items on the stack and push their sum on to the stack. (remember you can add negative numbers, so you have subtraction covered too). You can also get multiplication my creating a loop using some of the other instructions with this one.
ifeq <address> # examine the top of the stack, if it's 0, continue, else, jump to <address> where <address> is a line number
jump <address> # jump to a line number
print # print the value at the top of the stack
dup # push a copy of what's at the top of the stack back onto the stack.
Once you've written a program that can take these instructions and execute them, you've essentially created a very simple stack based virtual machine. Since this is a very low level language, you won't need to understand what an AST is, how to parse a grammar into an AST, and translate it to machine code, etc. That's too complicated for a tutorial project. Start with this, and once you've created this little VM, you can start thinking about how you can translate some common constructs into this machine. e.g. you might want to think about how you might translate a C if/else statement or while loop into this language.
Edit:
From the comments below, it sounds like you need a bit more experience with C before you can tackle this task.
What I would suggest is to first learn about the following topics:
scanf, printf, putchar, getchar - basic C IO functions
struct - the basic data structure in C
malloc - how to allocate memory, and the difference between stack memory and heap memory
linked lists - and how to implement a stack, then perhaps a binary tree (you'll need to
understand structs and malloc first)
Then it'll be good to learn a bit more about the string.h library as well
- strcmp, strdup - a couple useful string functions that will be useful.
In short, C has a much higher learning curve compared to python, just because it's a lower level language and you have to manage your own memory, so it's good to learn a few basic things about C first before trying to write an interpreter, even if you already know how to write one in python.
The only difference between an interpreter and a compiler is that instead of generating code from the AST, you execute it in a VM instead. Once you understand this, almost any compiler book, even the Red Dragon Book (first edition, not second!), is enough.
I see this is a bit of a late reply, however since this thread showed up at second place in the result list when I did a search for writing an interpreter and no one have mentioned anything very concrete I will provide the following example:
Disclaimer: This is just some simple code I wrote in a hurry in order to have a foundation for the explanation below and are therefore not perfect, but it compiles and runs, and seems to give the expected answers.
Read the following C-code from bottom to top:
#include <stdio.h>
#include <stdlib.h>
double expression(void);
double vars[26]; // variables
char get(void) { char c = getchar(); return c; } // get one byte
char peek(void) { char c = getchar(); ungetc(c, stdin); return c; } // peek at next byte
double number(void) { double d; scanf("%lf", &d); return d; } // read one double
void expect(char c) { // expect char c from stream
char d = get();
if (c != d) {
fprintf(stderr, "Error: Expected %c but got %c.\n", c, d);
}
}
double factor(void) { // read a factor
double f;
char c = peek();
if (c == '(') { // an expression inside parantesis?
expect('(');
f = expression();
expect(')');
} else if (c >= 'A' && c <= 'Z') { // a variable ?
expect(c);
f = vars[c - 'A'];
} else { // or, a number?
f = number();
}
return f;
}
double term(void) { // read a term
double t = factor();
while (peek() == '*' || peek() == '/') { // * or / more factors
char c = get();
if (c == '*') {
t = t * factor();
} else {
t = t / factor();
}
}
return t;
}
double expression(void) { // read an expression
double e = term();
while (peek() == '+' || peek() == '-') { // + or - more terms
char c = get();
if (c == '+') {
e = e + term();
} else {
e = e - term();
}
}
return e;
}
double statement(void) { // read a statement
double ret;
char c = peek();
if (c >= 'A' && c <= 'Z') { // variable ?
expect(c);
if (peek() == '=') { // assignment ?
expect('=');
double val = expression();
vars[c - 'A'] = val;
ret = val;
} else {
ungetc(c, stdin);
ret = expression();
}
} else {
ret = expression();
}
expect('\n');
return ret;
}
int main(void) {
printf("> "); fflush(stdout);
for (;;) {
double v = statement();
printf(" = %lf\n> ", v); fflush(stdout);
}
return EXIT_SUCCESS;
}
This is an simple recursive descend parser for basic mathematical expressions supporting one letter variables. Running it and typing some statements yields the following results:
> (1+2)*3
= 9.000000
> A=1
= 1.000000
> B=2
= 2.000000
> C=3
= 3.000000
> (A+B)*C
= 9.000000
You can alter the get(), peek() and number() to read from a file or list of code lines. Also you should make a function to read identifiers (basically words). Then you expand the statement() function to be able to alter which line it runs next in order to do branching. Last you add the branch operations you want to the statement function, like
if "condition" then
"statements"
else
"statements"
endif.
while "condition" do
"statements"
endwhile
function fac(x)
if x = 0 then
return 1
else
return x*fac(x-1)
endif
endfunction
Obviously you can decide the syntax to be as you like. You need to think about ways of define functions and how to handle arguments/parameter variables, local variables and global variables. If preferable arrays and data structures. References∕pointers. Input/output?
In order to handle recursive function calls you probably need to use a stack.
In my opinion this would be easier to do all this with C++ and STL. Where for example one std::map could be used to hold local variables, and another map could be used for globals...
It is of course possible to write a compiler that build an abstract syntax tree out of the code. Then travels this tree in order to produce either machine code or some kind of byte code which executed on a virtual machine (like Java and .Net). This gives better performance than naively parse line by line and executing them, but in my opinion that is NOT writing an interpreter. That is writing both a compiler and its targeted virtual machine.
If someone wants to learn to write an interpreter, they should try making the most basic simple and practical working interpreter.