2015-03-08 23 views
1

我正在学习编程ALSA通过this article和我试图编译下面的例子:为什么gcc99指向无意义的错误,而标准的gcc却没有?

/* 

This example opens the default PCM device, sets 
some parameters, and then displays the value 
of most of the hardware parameters. It does not 
perform any sound playback or recording. 

*/ 

/* Use the newer ALSA API */ 
#define ALSA_PCM_NEW_HW_PARAMS_API 

/* All of the ALSA library API is defined 
* in this header */ 
#include <alsa/asoundlib.h> 

int main() { 
    int rc; 
    snd_pcm_t *handle; 
    snd_pcm_hw_params_t *params; 
    unsigned int val, val2; 
    int dir; 
    snd_pcm_uframes_t frames; 

    /* Open PCM device for playback. */ 
    rc = snd_pcm_open(&handle, "default", 
        SND_PCM_STREAM_PLAYBACK, 0); 
    if (rc < 0) { 
    fprintf(stderr, 
      "unable to open pcm device: %s\n", 
      snd_strerror(rc)); 
    exit(1); 
    } 

    /* Allocate a hardware parameters object. */ 
    snd_pcm_hw_params_alloca(&params); 

    /* Fill it in with default values. */ 
    snd_pcm_hw_params_any(handle, params); 

    /* Set the desired hardware parameters. */ 

    /* Interleaved mode */ 
    snd_pcm_hw_params_set_access(handle, params, 
         SND_PCM_ACCESS_RW_INTERLEAVED); 

    /* Signed 16-bit little-endian format */ 
    snd_pcm_hw_params_set_format(handle, params, 
           SND_PCM_FORMAT_S16_LE); 

    /* Two channels (stereo) */ 
    snd_pcm_hw_params_set_channels(handle, params, 2); 

    /* 44100 bits/second sampling rate (CD quality) */ 
    val = 44100; 
    snd_pcm_hw_params_set_rate_near(handle, 
           params, &val, &dir); 

    /* Write the parameters to the driver */ 
    rc = snd_pcm_hw_params(handle, params); 
    if (rc < 0) { 
    fprintf(stderr, 
      "unable to set hw parameters: %s\n", 
      snd_strerror(rc)); 
    exit(1); 
    } 

    /* Display information about the PCM interface */ 

    printf("PCM handle name = '%s'\n", 
     snd_pcm_name(handle)); 

    printf("PCM state = %s\n", 
     snd_pcm_state_name(snd_pcm_state(handle))); 

    snd_pcm_hw_params_get_access(params, 
          (snd_pcm_access_t *) &val); 
    printf("access type = %s\n", 
     snd_pcm_access_name((snd_pcm_access_t)val)); 

    snd_pcm_hw_params_get_format(params, (snd_pcm_format_t *) &val); 
    printf("format = '%s' (%s)\n", 
    snd_pcm_format_name((snd_pcm_format_t)val), 
    snd_pcm_format_description(
          (snd_pcm_format_t)val)); 

    snd_pcm_hw_params_get_subformat(params, 
         (snd_pcm_subformat_t *)&val); 
    printf("subformat = '%s' (%s)\n", 
    snd_pcm_subformat_name((snd_pcm_subformat_t)val), 
    snd_pcm_subformat_description(
         (snd_pcm_subformat_t)val)); 

    snd_pcm_hw_params_get_channels(params, &val); 
    printf("channels = %d\n", val); 

    snd_pcm_hw_params_get_rate(params, &val, &dir); 
    printf("rate = %d bps\n", val); 

    snd_pcm_hw_params_get_period_time(params, 
            &val, &dir); 
    printf("period time = %d us\n", val); 

    snd_pcm_hw_params_get_period_size(params, 
            &frames, &dir); 
    printf("period size = %d frames\n", (int)frames); 

    snd_pcm_hw_params_get_buffer_time(params, 
            &val, &dir); 
    printf("buffer time = %d us\n", val); 

    snd_pcm_hw_params_get_buffer_size(params, 
         (snd_pcm_uframes_t *) &val); 
    printf("buffer size = %d frames\n", val); 

    snd_pcm_hw_params_get_periods(params, &val, &dir); 
    printf("periods per buffer = %d frames\n", val); 

    snd_pcm_hw_params_get_rate_numden(params, 
           &val, &val2); 
    printf("exact rate = %d/%d bps\n", val, val2); 

    val = snd_pcm_hw_params_get_sbits(params); 
    printf("significant bits = %d\n", val); 

    snd_pcm_hw_params_get_tick_time(params, 
            &val, &dir); 
    printf("tick time = %d us\n", val); 

    val = snd_pcm_hw_params_is_batch(params); 
    printf("is batch = %d\n", val); 

    val = snd_pcm_hw_params_is_block_transfer(params); 
    printf("is block transfer = %d\n", val); 

    val = snd_pcm_hw_params_is_double(params); 
    printf("is double = %d\n", val); 

    val = snd_pcm_hw_params_is_half_duplex(params); 
    printf("is half duplex = %d\n", val); 

    val = snd_pcm_hw_params_is_joint_duplex(params); 
    printf("is joint duplex = %d\n", val); 

    val = snd_pcm_hw_params_can_overrange(params); 
    printf("can overrange = %d\n", val); 

    val = snd_pcm_hw_params_can_mmap_sample_resolution(params); 
    printf("can mmap = %d\n", val); 

    val = snd_pcm_hw_params_can_pause(params); 
    printf("can pause = %d\n", val); 

    val = snd_pcm_hw_params_can_resume(params); 
    printf("can resume = %d\n", val); 

    val = snd_pcm_hw_params_can_sync_start(params); 
    printf("can sync start = %d\n", val); 

    snd_pcm_close(handle); 

    return 0; 
} 

的问题是,如果我

GCC test.c的编译-std = C99 -lasound

我得到如下:

test.c: In function ‘main’: 
test.c:36:3: warning: implicit declaration of function ‘alloca’ [-Wimplicit-function-declaration] 
    snd_pcm_hw_params_alloca(&params); 
^

但是,如果我不使用此警告不会出现

-std = C99

  1. 为什么我甚至得到这样的警告?
  2. 为什么标准C版本没有这样的问题?
+1

我会从错误消息'snd_pcn_hw_params_alloca'实际上是一个'#define'宏观的东西,涉及到猜'alloca',这是一个不属于标准C的函数。'-std = c99'是标准版本;如果你没有标志,那么你会得到包含'alloca'的GNU扩展。 – 2015-03-08 21:55:07

+0

为了解决这个问题,寻找一个不同的函数/宏来分配或初始化没有提及alloca的'params'。 – 2015-03-08 21:57:15

+3

这不是一个没有意义的错误。 – 2015-03-08 22:18:48

回答

4

根据man alloca那么当您使用alloca()添加alloca.h到您的包括:

#include <alloca.h> 

这不是通常的功能,因为它应该直接修改从它被调用的函数的栈。它是在编译器特殊处理,例如在GCC上GNU版本

Normally, gcc(1) translates calls to alloca() with inlined code. 
    This is not done when either the -ansi, -std=c89, -std=c99, or the 
    -std=c11 option is given and the header <alloca.h> is not included. 
    Otherwise, (without an -ansi or -std=c* option) the glibc version of 
    <stdlib.h> includes <alloca.h> and that contains the lines... 

您正在使用alloca因为snd_pcm_info_alloca(如所描述的in the man

注释被定义为宏alloca(谢谢,Matt McNabb)

#define snd_pcm_info_alloca(ptr) do { assert(ptr); *ptr = (snd_pcm_info_t *) alloca(snd_pcm_info_sizeof()); memset(*ptr, 0, snd_pcm_info_sizeof()); } while (0) 

不完全ALSA doc about snd_pcm_info_alloca

snd_pcm_hw_params_alloca(PTR) 使用标准ALLOCA

分配无效snd_pcm_hw_params_t但ALLOCA不是标准;当你使用它,你应该包括alloca.h

我认为这个例子在http://www.linuxjournal.com/article/6735?page=0,1是不正确的;像http://webpages.lss.supelec.fr/perso/kowalski/?download=playback.chttps://gitorious.org/alsa/alsa-tools/source/f768eb0ff4124ac7e795cee09acb797fd01b63f1:ac3dec/output.c这样的好例子有#include <alloca.h>

snd_pcm_hw_params_alloca宏应该谨慎使用,不正确使用可能会导致以后没有错误的使用方法:http://mailman.alsa-project.org/pipermail/alsa-devel/2008-March/006700.html

+1

这是alsa-lib中的一个错误,他们应该修复它们的头文件。 – ouah 2015-03-08 22:18:30

相关问题