Error multiple storage classes in declaration specifiers

Почему не могут использоваться классы статических и регистров хранения? При определении переменной следующим образом: Есть ли какая-то фундаментальная причина этой ошибки? Почему переменная не может храниться в регистре, а также быть инициализирована только при запуске/первом вызове? К классу хранения регистров можно присоединить глобальную переменную. Лучший ответ: Если компилятор реализовал то, что вы хотели добросовестно, […]

Содержание

  1. Почему не могут использоваться классы статических и регистров хранения?
  2. multiple storage classes in declaration specifiers
  3. Почему нельзя использовать классы статического и регистрового хранилища вместе?
  4. 3 ответа
  5. Почему нельзя использовать классы статического и регистрового хранилища вместе?
  6. 3 ответа
  7. C register keyword
  8. The idea
  9. C register – example in code
  10. Restrictions
  11. Usage in practice

Почему не могут использоваться классы статических и регистров хранения?

При определении переменной следующим образом:

Есть ли какая-то фундаментальная причина этой ошибки? Почему переменная не может храниться в регистре, а также быть инициализирована только при запуске/первом вызове? К классу хранения регистров можно присоединить глобальную переменную. Лучший ответ:

Если компилятор реализовал то, что вы хотели добросовестно, тогда он привязал регистр CPU для длины вашей программы. Это вряд ли практично.

Помните, что register является только рекомендательным.

Стандарт не позволяет использовать в объявлении более одного спецификатора класса хранения.

Из стандарта C99:

6.7.1 Спецификаторы класса хранения

1 спецификация хранилища-хранилища:

2 Максимум один спецификатор класса хранения может быть указан в спецификаторах декларации в объявлении.

Основная причина заключается в том, что квалификатор register подразумевает, что переменная имеет продолжительность автоматического хранения. Это, в основном, автоматическая переменная, для которой вы сообщаете компилятору, что было бы неплохо разместить ее в регистре CPU общего назначения.

статический определитель подразумевает статическую или длительность хранения потоков.

Очевидно, что эти два несовместимы, если они применяются к одной и той же переменной!

Это будет похоже на то, чтобы иметь переменную, которая умирает и выживает (в то же время), когда удаляемая запись активации удаляется.

Источник

multiple storage classes in declaration specifiers

When I try to compile these two following files I always get the error message
file1.c: In function ‘main’:
file1.c:8: error: multiple storage classes in declaration specifiers
Could anyone please help me in this regards

  1. .h
  2. #define NDATA 5
  3. float r[NDATA];
  1. #include «stdio.h»
  2. #include «dataread.h»
  3. extern float r[NDATA];
  4. int main()
  5. <
  6. extern void static data(float r[NDATA]);
  7. data(r);
  8. int i;
  9. for (i = 0; i Expand | Select | Wrap | Line Numbers
  1. #include «stdio.h»
  2. #include «dataread.h»
  3. extern float r[NDATA];
  4. void static data(float r[NDATA])
  5. <
  6. FILE *fo;
  7. int i;
  8. fo = fopen(«1.txt», «r»);
  9. /* Read data */
  10. for (i = 0; i 8 34498

  1. extern void static data(float r[NDATA]);

The static storage class declares the variable local to the file whereas the extern storage class declares the variable either external to the file or internal to the file but with external linkage.

Big conflict here so the compiler generates an error.

It looks like you want a global array:

  1. #include»test.h»
  2. int main()
  3. <
  4. float* ptr = data(); //get address of array
  5. >

So you call the data() function to get the address of the array.

Next in another .c file, you define the array as a static array. This makes access to the array local to the functions in the .c file where the array was defined. In this file you define the data function, which when called, returns the address of the array. Since the array is static, access form other files has to go through the data() function:

  1. static float r[NDATA];
  2. float* data()
  3. <
  4. return r;
  5. >

Lastly, write a header with the prototype of the data() function and include this header in all of yur other source files:

  1. #include «stdio.h»
  2. #include «dataread.h»
  3. float *data();
  4. int main()
  5. <
  6. float *ptr = data();
  7. int i;
  8. for (i = 0; i Expand | Select | Wrap | Line Numbers

This code in main():

Thank you. It works. However, when I tried this for a two column datafile in the follwing way:

1. In file2.c: Read data file, split columns and store each column in two files, define two function (float *grav_rad() and float *grav_dens()) for each array(column).

2. Call the function from file1.c and print the arrays

The compilation does not show any error, but when I run it I get the message: Segmentation fault

Please tell me where I am wrong and how can I fix the problem.

file1.c
1 #include «stdio.h»
2 #include «dataread.h»
3
4 float *grav_rad();
5 float *grav_dens();
6
7 int main()
8 <
9 float *ptr = grav_rad();
10 float *ptrho = grav_dens();
11 int i;
12
13 for (i = 0; i weaknessforcats

It looks like you are reading and writing floats to files. However, fscanf needs a delimiter so when you write to the file you need to separate your float values by a space.

A segmentation fault is always a memory corruption that you caused.

Also, there is no error checking in this code so you never know if the file opened or was read or written correctly.

Next, learn to use your debugger and step through this code a line at at time. The error will leap right out at you. This is better then putting in printf statements.

Источник

Почему нельзя использовать классы статического и регистрового хранилища вместе?

При определении переменной следующим образом:

Мы получаем ошибку:

Есть ли фундаментальная причина этой ошибки? Почему нельзя одновременно хранить переменную в регистре и инициализировать ее только при запуске / первом вызове? Можно присоединить класс хранения регистров к глобальной переменной. 3

3 ответа

Если компилятор добросовестно реализует то, что вы хотите, он будет связывать регистр ЦП на всю длину вашей программы. Это вряд ли практично.

Помните, что register носит рекомендательный характер.

Основная причина в том, что квалификатор register подразумевает, что переменная имеет автоматическую продолжительность хранения . По сути, это автоматическая переменная, которую вы сообщаете компилятору, что было бы хорошо поместить ее в регистр ЦП общего назначения.

Квалификатор static подразумевает статическую продолжительность хранения или хранения потока.

Очевидно, что эти два понятия несовместимы, если применять их к одной и той же переменной!

Это все равно что попросить переменную, которая умирает и выживает (одновременно), когда запись активации, которой она принадлежит, будет удалена.

Стандарт не позволяет использовать в объявлении более одного спецификатора класса хранения.

Из стандарта C99:

6.7.1 Спецификаторы класса хранения

2 В спецификаторах объявления в объявлении может быть указано не более одного спецификатора класса хранения.

Источник

Почему нельзя использовать классы статического и регистрового хранилища вместе?

При определении переменной следующим образом:

Мы получаем ошибку:

Есть ли фундаментальная причина этой ошибки? Почему нельзя одновременно хранить переменную в регистре и инициализировать ее только при запуске / первом вызове? Можно присоединить класс хранения регистров к глобальной переменной. 3

3 ответа

Если компилятор добросовестно реализует то, что вы хотите, он будет связывать регистр ЦП на всю длину вашей программы. Это вряд ли практично.

Помните, что register носит рекомендательный характер.

Основная причина в том, что квалификатор register подразумевает, что переменная имеет автоматическую продолжительность хранения . По сути, это автоматическая переменная, которую вы сообщаете компилятору, что было бы хорошо поместить ее в регистр ЦП общего назначения.

Квалификатор static подразумевает статическую продолжительность хранения или хранения потока.

Очевидно, что эти два понятия несовместимы, если применять их к одной и той же переменной!

Это все равно что попросить переменную, которая умирает и выживает (одновременно), когда запись активации, которой она принадлежит, будет удалена.

Стандарт не позволяет использовать в объявлении более одного спецификатора класса хранения.

Из стандарта C99:

6.7.1 Спецификаторы класса хранения

2 В спецификаторах объявления в объявлении может быть указано не более одного спецификатора класса хранения.

Источник

C register keyword

In C register keyword suggests to the compiler that the current variable should be stored in a CPU register, rather than memory.

The idea

The central processor can hold a very small amount of data. This data is stored in places called registers. Data saved there, is accessed faster than data stored in memory. For that reason programs can load their most-frequently accessed data in the CPU registers.

This is the very idea of the register keyword in C. It tells the compiler that we will work frequently with the current variable and it should be stored for fast access. Note that this is only a “hint” to the compiler and it could ignore it(and most likely it will, but more about this in a minute).

C register – example in code

Restrictions

Register is a storage class specifier. We cannot use more than one storage class specifier for one variable.
Attempting to assign more than one storage class specifier will result in an error like » error: multiple storage classes in declaration specifiers «

This means that the following declarations are not correct:

Placing a variable in a processor register means that it does not have a memory address, because it is not in the memory. Therefore, in C, if you declare a variable with the register keyword, you cannot access its address with the & operator.

Even if the variable is placed in memory, the compiler should not allow you to access its address. You can use this to make sure that some variable will not be changed outside of its function.
The following code should not compile. In my case it returns a compile-time error » error: address of register variable ‘number’ requested «

If it compiles, it should give a warning and chances are the program will crash.

If you use a C++ compiler: Many people are using C++ compilers to compile their C programs. This is OK, but it could cause some confusion, because in C++ it is allowed to access the address of a register variable.

Usage in practice

Back in the days compilers were not very good at deciding when to use machine registers for variables. For that reason the C developers did this manually with the register keyword.

With time the compilers got smarter. They became better than us in deciding about variables storage. Today it is very unlikely that a developer will make a better decision about a register variable. In fact, most of the time you could only make things slower. That’s why many compilers will always ignore the C register keyword when it comes to storage.

However, like we said earlier, you can use the C register keyword to make sure your variable will not be accessed by address and changed outside of the scope that you expect.

Источник

Every object in C has a storage duration, which is precisely one of the following: automatic, static, allocated, and (as of C11) thread-local.

With the exception of allocated storage, the storage duration of an object is determined by the linkage of the declared name that refers to the object. (Objects with allocated storage do not have any names associated with them.) Linkage of an identifier is determined by the storage-class specifier that is present in the declaration. Since an object can only have one type of linkage and one storage duration, the C language only allows you to specify one storage-class specifier (with an exception in C11 for _Thread_local).

The linkages and resulting storage durations are as follows:

  • static: internal linkage, static storage duration
  • extern: external linkage, static storage duration
  • auto, register: no linkage, automatic storage duration. Only allowed at block scope.
  • none: At block scope same as auto, at file scope same as extern.

As you can see, almost any two storage-class specifiers result in different, incompatible semantics. Therefore, the language simply forbids using more than one storage-class specifier, since for most combinations there it would not be clear which behaviour was requested. It seems that auto and register are the only two specifiers that could conceivably be applied together. C11 actually adds the exception that _Thread_local may appear together with either extern or static, resulting in the linkage of the latter and thread-local storage duration.

Different storage durations and linkages may require different implementations. Since variables with no linkage need to be unique per scope, they would usually be placed on the function call stack (if they need to be stored). By contrast, a variable with static storage duration needs to persist for the duration of the entire program and thus cannot be placed on a call stack, but instead needs to go in some other part of memory that’s available throughout.

4

When I try to compile these two following files I always get the error message
file1.c: In function ‘main’:
file1.c:8: error: multiple storage classes in declaration specifiers
Could anyone please help me in this regards

  1. .h
  2. #define NDATA 5
  3.         float r[NDATA];
  4.  

file1.c

  1. #include «stdio.h»
  2. #include «dataread.h»
  3.  
  4. extern float r[NDATA]; 
  5.  
  6. int main()
  7. {
  8.         extern void static data(float r[NDATA]);  
  9.  
  10.         data(r);
  11.         int i;
  12.  
  13.         for (i = 0; i<NDATA ; i++)
  14.         {   
  15.                 printf(«%f n», r[i]);
  16.         }   
  17. }
  18.  

file2.c

  1. #include «stdio.h»
  2. #include «dataread.h»
  3.  
  4. extern float r[NDATA];
  5.  
  6. void static data(float r[NDATA])  
  7.  
  8. {
  9.         FILE *fo;
  10.         int i;
  11.  
  12.         fo = fopen(«1.txt», «r»);
  13.  
  14.  
  15.         /* Read data */
  16.         for (i = 0; i<NDATA; i++)
  17.         {   
  18.                 fscanf(fo, «%f», &r[i]);    
  19.                 printf(» read line %d %fn», i, r[i]); 
  20.         }   
  21.  
  22.         return;
  23.  
  24. }

Oct 6 ’11
#1

Storage class

  • Storage classes only decides scope, visibility and lifetime of that variable. Storage classes tells where will be the variable to stored. What is the default initial value of the variable
  • Scope : The scope of a variable refers extent to which different part of programs have access to the variable,(Where the variable is visible).
  • Lifetime: Lifetime means how long the variable persist in memory (or) when the variable’s storage is allocated and deallocated, scope also affects a variable’s lifetime.
  • variable types(Global variable)
    • Global variable. (outside of the function, include main() is called it)
      • life time : only destroy when program terminates
      • scope : only the programs
    • local variable. (inside the function
      • life time : when enters inside the function its allocated the memory, and destroy when goes to out of function.
      • scope : only that inside the function.
  • syntax:
    • storage_class_specifier data_type variable_name;
  • Specifiers : auto
    • Lifetime : Block (or) inside function (or) within function
    • Scope : Block
    • Default initialize : Uninitialized
  • Specifiers : register
    • Lifetime : Block (stack or CPU register)
    • Scope : Block
    • Default initialize : Uninitialized
  • Specifiers : static
    • Lifetime : Program
    • Scope : Block or compilation unit
    • Default initialize : Zero
  • Specifiers : extern
    • Lifetime : Program
    • Scope : Block or compilation unit
    • Default initialize : Zero
  • Specifiers : (none)1
    • Lifetime : Dynamic (heap)
    • Scope : nil
    • Default initialize : Uninitialized

auto keyword

  • A variable declare in the inside a function without any storage class specification or specified auto called auto variable.
  • Auto can only be used within functions
  • They are crated when a function is called and are destroyed automatically when the functions exits.
  • By defalt they are assigned garbage value by the compiler.
  • local variable (All the local variables are stored in a memory called as stack memory)
  • By default every local variable of the function is auto storage class.
  • Example
    • void f() //function start
      {
         int i; // auto variable
         auto int j; //auto variable
      }

Global variable

  • A variable declared outside any function is a global variable.
  • its value can be changed by any function in the program.
  • initializing
    • int 0
    • char
    • float0
    • double0
    • pointernull

register keyword

Used to define local variables that should be stored in a register instead of RAM memory (eg :Quick access such as counters). register variable has faster access than a normal variable. frequently used variables are kept in register. only few variable can be placed inside register. . The keyword register hints to compiler that a given variable can be put in a register. It’s compiler’s choice to put it in a register or not. Generally, compilers themselves do optimizations and put the variables in register.

Register Note 1 :

  • accessing address of a register is invalid : Note : if we try to take “Register’s” Address its gives Compile error, we cannot take the address of a register variable. See below Example.
int main() 
{ 
  register int i = 10; 
  int *a = &i; 
  printf("%d", *a); 
  getchar(); 
  return 0; 
} 
/* prog.c:4:1: error: address of register variable 'i' requeste */

Register Note 2

  • 2 register keyword can be used with pointer variables. Obviously, a register can have address of a memory location. There would not be any problem with the below program. See Example.
int main() 
{ 
  int i = 10; 
  register int *a = &i; 
  printf("%d", *a); 
  getchar(); 
  return 0; 
}
/*Output : 100 */

Resistor Note 3:

  • Register is a storage class, and C doesn’t allow multiple storage class specifiers for a variable. So, register can not be used with static .
int main() 
{ 
  int i = 10; 
  register static int *a = &i; 
  printf("%d", *a); 
  getchar(); 
  return 0; 
}
/* Error:
Line 5:3: error: multiple storage classes in declaration specifiers
   register static int *a = &i; */

Register Note 4:

  • There is no limit on number of register variables in a C program, but the point is compiler may put some variables in register and some not.

static keyword

  • static means its take only single or same memory.
  • static is initialized only once and remains into existence till the end of program
  • static assigned 0 (zero) as default value by the compiler.
  • A static local variables retains its value between the function call and the default value is 0.
  • If a global variable is static then its visibility is limited to the same source code.
  • Static variables stored in Heap(Not in Stack memory)
  • The following function will print 1 2 3 if called thrice.
  • Example
    • void f()
      {
          static int i;
          ++i;
          printf(“%d “,i);
      }
  • static int a[20];  here variable a is declared as an integer type and static. If a variable is declared as static and it will be automatically initialized to value ‘0’ (zero).

What is a static function?

  • A function’s definition prefixed with static keyword is called as a static function.
  • You would make a function static if it should be called only within the same source code (or) that are only visible to other functions in the same file
  • static has different meanings in in different contexts.
  • When specified on a function declaration, it makes the function local to the file.
  • When specified with a variable inside a function, it allows the vairable to retain its value between calls to the function

storage class specifier

  • typedeftypedef is the storage class specifier.
    • its does not reserve the storage.
    • It is used to alias the existing type. Also used to simplify the complex declaration of the type.
  • reference links
    • https://en.wikipedia.org/wiki/C_syntax

volatile

  • Objects declared as volatile are omitted from optimization because their values can be changed by code outside the scope of current code at any time

What are storage classes in ‘C’ language?

  • automatic class
  • static class

How many storage class specifiers in “C” language?

  • auto,
  • register,
  • static
  • extern

How many variables scopes are there in “C” language?

  • Body.
  • Function.
  • Program.
  • File.

  1. Home
  2. C Keywords
  3. register

C register keyword

In C register keyword suggests to the compiler that
the current variable should be stored in a CPU register, rather than memory.

The idea

City Football Manager

The central processor can hold a very small amount of data. This data is stored in places called registers. Data saved there, is accessed faster than data stored in memory. For that reason programs can load their most-frequently accessed data in the CPU registers.

This is the very idea of the register keyword in C. It
tells the compiler that we will work frequently with the current
variable and it should be stored for fast access. Note that this is only
a “hint” to the compiler and it could ignore it(and most likely it
will, but more about this in a minute).

C register – example in code

int values[5];
register int i;
for(i = 0; i < 5; ++i)
{
    values[i] = i;
}

Restrictions

Register is a
storage class specifier. We cannot use more than one storage class specifier for one variable.
Attempting to assign more than one storage class specifier will result in an error like «error: multiple storage classes in declaration specifiers«

This means that the following declarations are not correct:

Placing a variable in a processor register
means that it does not have a memory address, because it is not in the memory.
Therefore, in C, if you declare a variable with the register keyword, you
cannot access its address
with the & operator.

Even if the variable is placed in memory,
the compiler should not allow you to access its address. You can use this to
make sure that some variable will not be changed outside of its function.
The following code should not compile. In my case it returns a compile-time error «error: address of register variable ‘number’ requested«

If
it compiles, it should give a warning and chances are the program will crash.

1
2
3
4
5
6
7
8
int main()
{
    register int number = 1;
    scanf("%d", &number);
    printf("%d", number);

    return 0;
}

If you use a C++ compiler: Many people are using C++ compilers to compile their C programs.
This is OK, but it could cause some confusion, because in C++ it is allowed to
access the address of a register variable.

Usage in practice

Hardly any.

Back in the days compilers were not very
good at deciding when to use machine registers for variables. For that reason
the C developers did this manually with the register keyword.

With time the compilers got
smarter. They became better than us in deciding about variables storage. Today it is very unlikely that a developer will make a
better decision about a register variable. In fact, most of the time you could
only make things slower. That’s why many compilers will always ignore the C
register keyword when it comes to storage.

However, like we said earlier, you can use the C register keyword to make sure your variable will not be accessed by address and changed outside of the scope that you expect.

See also:

  • auto
  • extern
  • static
  1. Home
  2. C Keywords
  3. register

Re:Variable visibility during debugging — «out of scope» msg.


2010/12/10 03:49:38

(permalink)

Posting here for joelty…

Since this post, I structure my code a little differently. The out of scope message appears if you’re debugging code in a different module to where the variable is declared. The best solution I’ve found to this is as follows, adapted from someone else’s suggestion:

Create two files, globals.h and globals.c.

<forum not accepting example code — potentially harmful?… sigh…>

In globals.h, use an ifndef preprocessor to stop the compiler defining multiple times. Then declare the variables as extern, and do not initialise.

In globals.c, include the globals.h file, and declare and initialise the variables to 0 or whatever you want. The variables are not extern here.

Finally, in for example the main.c file, using the variable like so:

 #include globals.h            // Include the Globals.h header to use the variables 
/*...various code or whatever...*/
     variable1 = U1RXREG; // read the receive buffer into the unsigned char
/*... more code...*/

This approach has simplified variable declaration and debugging for me. When I want a new variable, I add it into globals.h as an extern <variable type> int, long, unsigned int or whatever, and without the extern usage, and initialised (usually to 0) in the globals.c file. 

It’s then available to all the C files in my project, and I can split up the code into «interrupts», «main», and whatever other files I’m using, say for the LCD or other areas. 

This is so far the most flexible way I’ve found of variable declaration, which will mean that the debugger always sees the variable value, and doesn’t wait until it’s declared in a function. So, if your code is calling various functions, it makes it a bit easier from the debugging point of view.

Понравилась статья? Поделить с друзьями:
  • Error multiple accounts are not allowed
  • Error multipart boundary not found
  • Error multilib version problems found
  • Error multidimensional array must have bounds for all dimensions except the first
  • Error mugen character