Is there a way to protect a variable for modification at run time in C?

I was wondering if there is a way to protect the variable for modification after initialization (something like "constantizing" the variable at run time). For instance:

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

int main(void)
{
    int v, op;
    scanf( "%d", &op );
    if( op == 0 )
        v = 1;
    else
        v = 2;
// here transform v to a constant...
    .
    .
// ...and that any attempt to modify v yields to an error.
    .
    .
    return EXIT_SUCCESS;
}
0
source share
4 answers

You can make the input result constas follows:

int func()
{
    int op = 0;
    scanf( "%d", &op );
    if( op == 0 )
        return 1;
    else
        return 2;
}

int main()
{
    const int v = func();
    // ...
}

NB. Of course, there is no way to prevent undefined behavior from occurring later in the program, which seems to change v(since undefined behavior can, by definition, have any effect).

+3
source

Yes: code coefficient:

foo.h:

void do_something(int arg);

foo.c:

#include "foo.h"

void do_something(int arg)
{
    // implement
    //
    // Here "arg" is completely under your control.
}

foo_test.c:

#include "foo.h"

// add unit tests for do_something

main.c:

#include <stdio.h>
#include <stdlib.h>
#include "foo.h"

int main(void)
{
    int op;
    if (scanf("%d", &op) != 1) { abort(); }

    do_something(op == 0 ? 1 : 2);
}

, do_something - .

+1

const:

const int i = 5;

Hoever, , , . , .

, , const, undefined bahaviour , , , const .

, static ( ), - / ( static). setter/getter:

"wrapper.h":

#ifndef WRAPPER_H
#define WRAPPER_H

extern void set_once(int v);
extern int get_value(void);

#endif

"wrapper.c":

#include <stdbool.h>
#include "wrapper.h"

static struct {
    bool is_set;    // guaranteed false on startup
    int value;
} my_var;

void set_once(int v)
{
    if ( !my_var.is_set )
        my_var.value = v;
    else
        ; // report an error, e.g. abort()
}

int get_value(void)
{
    if ( !my_var.is_set )
        return my_var.value;
    // report an error, e.g. abort()
}

"main.c"

#include "wrapper.h"

int main(void)
{
    set_once(5);
    int i = get_value();
}

, , . , , 0 ( false). , , , , / (, assert).

Edit:

. , , , . , , . gcc- , -fplan9-extensions. .

@MattMcNabb.

+1

, .

You can do it const, but it’s an easier hint, and you can drop it with almost any effort. In addition, if you have a pointer to something, you can always change it with direct memory access.

You can also hide it inside the class that controls access to the record, but you are in the same situation as in the first case - a pointer to it.

0
source

All Articles