简体   繁体   English

定义有什么问题?

[英]What's wrong with the definition?

I'm trying to compile "libsamplerate.dll" with Visual Studio VC++ 2015 on Windows10, referring to: http://www.mega-nerd.com/SRC/win32.html . 我正在尝试在Windows10上使用Visual Studio VC ++ 2015编译“ libsamplerate.dll”,请参阅: http : //www.mega-nerd.com/SRC/win32.html

Then, I got the following errors: 然后,出现以下错误:

termination_test.c
.\tests\termination_test.c(82): error C2057: expected constant expression
.\tests\termination_test.c(82): error C2466: cannot allocate an array of constant size 0
.\tests\termination_test.c(82): error C2133: 'in': unknown size
.\tests\termination_test.c(83): error C2057: expected constant expression
.\tests\termination_test.c(83): error C2466: cannot allocate an array of constant size 0
.\tests\termination_test.c(83): error C2133: 'out': unknown size
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\cl.exe"' : return code '0x2'

"termination_test.c" is originally from: http://www.mega-nerd.com/SRC/download.html and here is the function which causes the errors: “ termination_test.c”最初来自: http : //www.mega-nerd.com/SRC/download.html ,这是导致错误的函数:

static void
simple_test (int converter)
{
    int ilen = 199030, olen = 1000, error ;

    {
        float in [ilen] ;
        float out [olen] ;
        double ratio = (1.0 * olen) / ilen ;
        SRC_DATA src_data =
        {   in, out,
            ilen, olen,
            0, 0, 0,
            ratio
        } ;

        error = src_simple (&src_data, converter, 1) ;
        if (error)
        {   printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
            exit (1) ;
            } ;
    } ;

    return ;
} /* simple_test */

I simply modified these two lines to: 我只是将这两行修改为:

        float in [199030] ;
        float out [1000] ;

... then, worked perfectly. ...然后,完美地工作了。

However, what's wrong with the definition? 但是,定义出了什么问题?

int ilen = 199030, olen = 1000, error ;

I put 'const' in front of int, then I got another error "C2166: l-value specifies const object". 我将'const'放在int前面,然后出现另一个错误“ C2166:l值指定了const对象”。 How can I make it error-free? 如何使它没有错误?

(PS, This is an open-source code, so there shouldn't be any errors. This isn't a question, but I just wonder why.) (PS,这是一个开源代码,因此不应有任何错误。这不是问题,但我只是想知道为什么。)

Visual Studio doesn't support variable length arrays. Visual Studio不支持可变长度数组。

The variables ilen and olen that defined the size of the array are not constant expressions (from here on described as: constants), so the following are variable length arrays: 定义数组大小的变量ilen和olen不是常量表达式(从这里开始描述为:常量),因此以下是可变长度数组:

float in [ilen] ;
float out [olen] ;

Values 199030 and 1000 are constants, so the following are just regular arrays: 值199030和1000是常量,因此以下只是常规数组:

float in [199030] ;
float out [1000] ;

Defining an object with a const qualifier will not make an object a constant. 用const限定符定义对象不会使对象成为常量。

You can use #define to define your values as macros, but this is identical to writing the constants manually, as the defined macros are replaced before compiling the code with the values they denote. 您可以使用#define将值定义为宏,但这与手动编写常量相同,因为在用它们所表示的值编译代码之前,已定义的宏将被替换。

#define ILEN 1000
int array[ILEN];

is converted to: 转换为:

int array[1000];

before before compiling begins. 在开始编译之前。

Of course you should use #define as it is much more convenient and less error-prone. 当然,您应该使用#define因为它更加方便且不易出错。

Continuing from the comment, the subtle point you were missing is that in C, array declaration requires a constant expression for the array size (eg array[CONST] ). 继续从注释开始,您缺少的一个微妙之处是,在C语言中,数组声明需要一个用于数组大小的常量表达式(例如array[CONST] )。 fn1. fn1。 When you declare: 当您声明:

int ilen = 199030, olen = 1000, error ;

Neither ilen or olen are constant expressions . ilenolen都不是常量表达式 (the easy way to think about it is you could easily do ilen = ilen + 2; -- so ilen isn't a constant expression .) (思考的简单方法是,您可以轻松地执行ilen = ilen + 2; -因此ilen不是常数表达式 。)

Constant expressions are generally created by macro with #define or enum (which create global constants). 常量表达式通常由带有#defineenum的宏创建(它们创建全局常量)。 (and you generally CAPITALIZE constants -- just to distinguish then from other variables). (并且通常使用CAPITALIZE常量-只是为了区别于其他变量)。 So you could do: 因此,您可以执行以下操作:

#define ILEN 199030
#defile OLEN 1000

or 要么

enum { OLEN = 1000, ILEN = 199030 };

and then declare your float arrays: 然后声明您的float数组:

float in [ILEN],
     out [OLEN];

fn 1. Modern C compilers allow allow the use of the variable length array which can be declared in the way you have attempted, but as others have pointed out, your compiler does not support VLAs. fn 1.现代C编译器允许使用可变长度数组 ,该数组可以按照您尝试的方式进行声明,但是正如其他人指出的那样,您的编译器不支持VLA。

The size of an array, at least in C89, must be a costant expression. 数组的大小(至少在C89中)必须是重要的表达式。 A costant expression is an expression whose value doesn't change. 强制表达式是其值不变的表达式。 Here's few examples of constant expressions: 以下是常量表达式的一些示例:

#define SIZE (200)
...
int v[200];/* Ok*/
int w[200 + 1]; /*Ok because 200 + 1 does always 201*/
int y[SIZE]; /* Better*/
...

This implies that you cannot use a variabile to specify the array size, even if you declare it using "const" keyword because you fan change value of a const value by taking advantage of pointers. 这意味着即使使用“ const”关键字声明变量也不能使用可变变量来指定数组大小,因为您可以利用指针来改变const值的值。

int n = 10;
const int size = 10;
int v[n]; /* Wrong in C89 and non C99 fully compliant compilers!*/
int x[size]; /* Again, not valid because costant value != costant expression*/

To verify that const value can be changed,try this: 要验证const值是否可以更改,请尝试以下操作:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    const int a = 0;
    int *p = &a;
    printf("Now a is %d\n",a);
    *p = 1;
    printf("Now a is %d\n",a);
    return EXIT_SUCCESS;


}

You'll see that a's value changes after the first call to printf. 您将看到在第一次调用printf之后a的值发生了变化。 This behaviour is anyway compiler-dependant,in fact GCC allows you to change a const value but clang doesn't. 无论如何,此行为取决于编译器,实际上GCC允许您更改const值,但clang不允许。 That's why you can't use variables for the size of an array. 这就是为什么您不能使用变量作为数组的大小。 C99 standards introduced VLAs (Variable Lenghts Arrays) and many other orrible features. C99标准引入了VLA(可变长度阵列)和许多其他糟糕的功能。 With -std=c99 flag (or equivalent for non-GCC compatible compilers) you can use variables for specifying the size of an array, but this is a bad thing to do because it hides a call to malloc. 使用-std = c99标志(或与非GCC兼容的编译器等效的标志),您可以使用变量指定数组的大小,但这是不好的事情,因为它隐藏了对malloc的调用。 C99 extensions were substantially introduced on favor of GCC and Numerical C and nowdays many compilers reject some features of C99 standards. 大量引入C99扩展是为了支持GCC和数值C,如今,许多编译器都拒绝了C99标准的某些功能。 Visual Studio compiler does not -rightly- support VLA,so you have two options: - use malloc - avoid dynamic memory (preferable) Visual Studio编译器不正确地支持VLA,因此您有两个选择:-使用malloc-避免动态内存(首选)

In serious contexts malloc is not an option since it is strictly forbidden by strict standards such as MISRA/C and NASA subset. 在严重的情况下,不能使用malloc,因为严格的标准(例如MISRA / C和NASA子集)严格禁止使用malloc。 But even in "not so critical" environment avoiding the use of malloc is a good practice because it makes easier for you to write predictable and bug free code since you don't have to worry about memory leaks, forgotten free() etc. The solution consists in allocating a big pool of memory at the very beginning of the program and using it when needed. 但是即使在“不是那么关键”的环境中,避免使用malloc也是一个好习惯,因为它使您更容易编写可预测且无错误的代码,因为您不必担心内存泄漏,忘记了free()等问题。解决方案包括在程序的开头分配一个大的内存池,并在需要时使用它。

To sum up the best way to declare an array is: 总结声明数组的最佳方法是:

#define SIZE (...)
...
int v[SIZE];
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM