jeudi 2 juillet 2015

Character vs strings in C

The C programming language distinguishes character constants from string constants by using single quotation marks for characters and double quotation marks for strings. Thus,'c' is the character c, while "c" is a string of length 1 consisting of the single character c.Why is this distinction is made? How is it useful?

What exactly is in a .o / .a / .so file?

I was wondering what exactly is stored in a .o or a .so file that results from compiling a C++ program. This post gives a quite good overview of the compilation process and the function of a .o file in it, and as far as I understand from this post, .a and .so files are just multiple .o files merged into a single file that is linked in a static (.a) or dynamic (.so) way.

But I wanted to check if I understand correctly what is stored in such a file. After compiling the following code

void f();
void f2(int);

const int X = 25;

void g() {
  f();
  f2(X);
}

void h() {
  g();
}

I would expect to find the following items in the .o file:

  • Machine code for g(), containing some placeholder addresses where f() and f2(int) are called.
  • Machine code for h(), with no placeholders
  • Machine code for X, which would be just the number 25
  • Some kind of table that specifies at which addresses in the file the symbols g(), h() and X can be found
  • Another table that specifies which placeholders were used to refer to the undefined symbols f() and f2(int), which have to be resolved during linking.

Then a program like nm would list all the symbol names from both tables.

I suppose that the compiler could optimize the call f2(X) by calling f2(25) instead, but it would still need to keep the symbol X in the .o file since there is no way to know if it will be used from a different .o file.

Would that be about correct? Is it the same for .a and .so files?

Thanks for your help!

printf() without '\n' doesn't work in libev

Post the code first:

#define EV_STANDALONE 1
#include <stdio.h>
#include "ev.c"

ev_timer timeout_watcher;
struct ev_loop* loop;
static void timeout_cb (EV_P_ ev_timer *w, int revents)
{
//    puts("timeout");
    printf("timeout");
    ev_timer_again(loop, w);
}
int main (void)
{
    printf("hello, world.");
    loop = EV_DEFAULT;
    ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
    timeout_watcher.repeat = 2.0;
    ev_timer_start (loop, &timeout_watcher);
    ev_run (loop, 0);
    return 0;
}

Strange thing happened while running: although the printf("hello, world."); was in the first place in main function, but it didn't work. But if I use printf("hello, world\n"); instead, things worked fine. Further more, I changed printf("hello, world"); instead of puts("hello, world");, it also worked. So what on earth did libev do to the io? Why "\n" matters?

Is there a way to find matching #if, #else, #elif & #endif in Eclipse?

I have some long C & C++ header files with a lot of nested #if statements in them.

#if FOO
    ...
#elif BLAR
    #ifndef WIDGET
    #endif
#else
    ...
#end

Is there a way to jump between matching statements in Eclipse? I have found a similar question that says it is possible in Visual Studio which suggests that the CTRL + ] key combination should do it, but that seems to only work for matching braces.

Assigning a string to a pointer in a struct

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Person {
        char *forename;
        char *surname;
        int age;
};

void change_struct(struct Person *person, char *forename, char *surname,
                int age);
void print_struct(struct Person *person);

int main(void)
{
        struct Person person1;
        person1.forename = malloc((strlen("Max") + 1) * sizeof(char));
        if (!person1.forename) {
                exit(EXIT_FAILURE);
        }
        strcpy(person1.forename, "Max");
        person1.surname = malloc((strlen("Mustermann") + 1) * sizeof(char));
        if (!person1.surname) {
                exit(EXIT_FAILURE);
        }
        strcpy(person1.surname, "Mustermann");
        person1.age = 35;

        print_struct(&person1);

        change_struct(&person1, "Hans", "Bauer", 45);

        print_struct(&person1);

        free(person1.forename);
        free(person1.surname);

        exit(EXIT_SUCCESS);
}

void change_struct(struct Person *person, char *forename, char *surname,
                int age)
{
        person->forename = realloc(person->forename,
                                   (strlen(forename) + 1) * sizeof(char));
        if (!person->forename) {
                exit(EXIT_FAILURE);
        }
        strcpy(person->forename, forename);
        person->surname = realloc(person->surname,
                                  (strlen(surname) + 1) * sizeof(char));
        if (!person->surname) {
                exit(EXIT_FAILURE);
        }
        strcpy(person->surname, surname);
        person->age = age;
}

void print_struct(struct Person *person)
{
        printf("%s\n", person->forename);
        printf("%s\n", person->surname);
        printf("%d\n", person->age);
}

When assigning a string to a pointer in a struct is it well-defined behavior if I would do

person1.forename = "Max";
person1.surname = "Mustermann";

in main() initially instead of using malloc() and strcpy()? (Of course in this specific case I would need to also change the realloc() calls in change_struct() since it is undefined behavior when realloc() receives a non- malloc(), calloc(), or realloc() created pointer.) If dynamic memory allocation should be required could you give an explanation why?

Why can't I compile this C API (NeMo Spiking Neural Network Simulator)

Hi I am trying to utilize this library http://ift.tt/1Nyk9EY to play around with Spiking Neural Networks.

I am new to C and C++.

What I've done is, downloaded the installer from here: http://ift.tt/1Nyk9F0

Installed.

I then wrote this program in main.c file:

#include<nemo.h>
#include<stdio.h>
#include<stdlib.h>

main()
{
    printf("Hello World!");
    getchar();      
}

and compiled it using MinGW on Windows:

gcc -I"C:\Program Files (x86)\NeMo\include" main.c -o main.exe

I get the following error:

In file included from main.c:1:0:
C:\Program Files (x86)\NeMo\include/nemo.h:48:1: error: unknown type name 'nemo_
network_class'
 typedef nemo_network_class* nemo_network_t;
 ^
C:\Program Files (x86)\NeMo\include/nemo.h:49:1: error: unknown type name 'nemo_
simulation_class'
 typedef nemo_simulation_class* nemo_simulation_t;
 ^
C:\Program Files (x86)\NeMo\include/nemo.h:50:1: error: unknown type name 'nemo_
configuration_class'
 typedef nemo_configuration_class* nemo_configuration_t;
 ^

Please help me.

It looks like nemo.h has problems, but I suspect I am missing something because I am a newbie...

What is EOF and what is its significance? How can it be noticed?

While studying getchar() function in C ,I came across this EOF being returned , I want to know how can its existence be noticed, where is it stored?

Can we type EOF character explicitly?