-qinfo

适用的调用

表 1. 接受给定选项的调用
选项 xlc (编译 C) xlC (编译 C++) xlclang(编译 C) xlclang++(编译 C++)
-qinfo    
注: 此表中仅列出典型调用。 对于所有基本调用及其等效特殊调用,您可以参阅 编译器调用的完整列表

类别

错误检查和调试

等效编译指示

#pragma 选项 [no] 信息, #pragma 信息

用途

生成或禁止参考消息组。

消息将写入标准输出, 还可选择写入到列表文件 (如果已生成)。 编译器不会针对以下文件发出消息:

语法

操作语法

读取语法图跳过可视语法图 -q noinfoinfo=:allnoallalsnoalsnogroupmtnomtprivatereductionstpnostp

编译指示语法

读取语法图跳过可视语法图#pragmainfo( ,allnonealsnoalsno 组mtnomtprivatereductionrestore )

缺省值

-qnoinfo

  • 仅限 C -qnoinfo
  • 仅限 C + + -qinfo=lan:trx

参数

全部
对除 alsmtppt以外的所有组启用诊断消息。
noall(仅选项)
为所有组禁用所有诊断消息。
无 (仅限编译指示)
为所有组禁用所有诊断消息。
als
允许报告生效的 ANSI 别名判别规则的可能违例。
诺尔斯
禁用报告可能的别名规则违例。
| 否
启用或禁用特定消息组,其中 group 可以是下列其中一项或多项:
返回或禁止的参考消息的类型。
仅限 C + + cls | nocls
C++ 类。
cmp | nocmp
unsigned 比较中可能存在冗余。
cnd | nocnd
条件表达式中可能存在冗余或问题。
cns | nocns
涉及常量的操作。
cnv | nocnv
转换。
dcl | nodcl
声明的一致性。
夫 | 诺夫
不起作用的语句和编译指示。
enu | noenu
enum 变量的一致性。
ext | noext
未使用的外部定义。
gen | nogen
常规诊断消息。
gnr | nognr
生成临时变量。
已获取 | 已获取
使用 goto 语句。
仅限 C ini | noini
报告部分初始化其数组的数组初始化程序。 如果已部分初始化数组,那么未初始化的 元素将接收到相应类型的值 0。
lan | nolan
语言级别影响。
obs | noobs
过时的功能部件。
奥德 | 诺德
未指定评估顺序。
par | nopar
未使用的参数。
por | nopor
不可移植语言构造。
ppc | noppc
使用预处理器时可能出现问题。
ppt | noppt
预处理器操作的跟踪。
pro | nopro
缺少函数原型。
rea | norea
无法访问的代码。
Ret | noret
返回语句的一致性。
trd | notrd
可能截断或丢失数据或精度。
tru | notru
编译器截断的变量名。
trx | notrx
十六进制-浮点常量舍入。
乌尼 | 努尼
未初始化的变量。 -qinfo=uni 选项强制实施必须在其声明中初始化变量的编码样式。
unset | nouset (仅选项)
检测在设置之前使用的自动变量,并在编译时用参考消息标记这些自动变量。

-qinfo=unset 使用优化期间可用的程序信息,例如控制流信息。 因此,检测精度会随优化级别提高。 例如,未在 -O0 处标记的未设置变量的某些使用在 -O2 处标记。 激进的优化级别,例如 -O4 和 -O5,会导致参考消息中的行号变得不准确。 在极少数情况下,这些优化级别会充分对程序进行重新排序,从而导致静态分析产生误报消息。 可以使用 -O2 优化级别获得最佳结果。

-qinitauto 选项用于初始化自动变量。 因此,-qinitauto 选项会隐藏在通过 -qinfo=unset 选项设置之前使用的变量。

upg | 名词
生成描述当前编译器发行版与先前发行版相比的新行为的消息。
使用 | nouse
未使用的自动变量和静态变量。
仅限 C + + vft | novft
生成虚拟函数表。
zea | nozea
零扩展数据块阵列。
mt | nomt

以并行代码报告潜在同步问题。 这一子选项将检测全局线程标志模式,其中一个线程使用共享的易变标志变量通知其他线程它已完成计算并将其结果存储到内存中。 其他线程在不更改标志变量的循环中检查标志变量。 当标志变量的值发生变化时,等待线程将从内存中访问计算结果。 在第一个线程中设置标志变量之前,以及在等待线程中检查标志变量之后, PowerPC® 存储模型需要同步。 可以通过同步内置函数来完成同步。

需要使用的同步伪指令的类型取决于您的代码。 通常,它足以使用 __lwsync 函数,因为它会保留对系统内存的存储器访问顺序。 但是,如果以这样的方式写入等待线程中的循环,即可能导致指令预取在更新标志变量之前开始执行访问计算结果的代码,那么需要 调用类似 __isync 的函数以保留顺序。 此类模式通常如下所示:
gotosleep: sleep(value);
   if (!flag) goto gotosleep;   
   // A call to the __isync function is needed here.   
   x = shared_computation_result;

一些不需要同步的模式与上述模式类似。 此子选项生成的消息只是关于潜在同步问题的建议。

要使用 -qinfo=mt 子选项,必须启用 -qthreaded 选项并至少指定下列其中一个选项:
  • -O3
  • -O4
  • -O5
  • -qipa
  • -qhot
  • -qsmp

缺省选项为 -qinfo=nomt

专用
建议不要使用此子选项。 -qreport 将其替换。 有关详细信息,请参阅 -qreport不推荐的选项
50%
建议不要使用此子选项。 -qreport 将其替换。 有关详细信息,请参阅 -qreport不推荐的选项
stp | nostp
针对不受堆栈损坏保护的过程发出警告。 除非还启用了 -qstackprotect 选项,否则 -qinfo=stp 没有任何影响。 与其他 -qinfo 选项一样, -qinfo=stp 通过 -qinfo=all/noall启用或禁用。 -qinfo=nostp 是缺省选项。
复原 (仅限编译指示)
废弃当前编译指示设置并还原为先前编译指示伪指令指定的设置。 如果未指定先前的编译指示,请还原为命令行或缺省选项设置。

使用量

指定不带子选项的 -qinfo 等同于 -qinfo=all

指定 -qnoinfo 等同于 -qinfo=noall

在启用对别名判别规则违例的报告时,请考虑以下事项:
  • 必须先设置 -qalias=ansi ,然后才能报告别名判别规则违例 (-qinfo=als)。
  • 任何级别的优化或直接插入都意味着 -qinfo=noals ,当显式指定 -qinfo=als 时将发出警告。
  • 诊断是探试性的,可能发出误报。 无法在静态编译中确定性地评估指向分析。 用于诊断的点对点分析以上下文和流的不敏感方式进行评估。 诊断中的回溯消息序列是这样,如果按指定的顺序执行,那么间接表达式将指向违例对象。 如果该执行序列无法在应用程序中出现,那么诊断为误报。 (请参阅 示例 部分以了解可能发生的诊断类型。)

预定义的宏

无。

示例

要编译 myprogram.c 以生成有关 除转换和未到达的语句以外的所有项的参考消息,请输入以下命令:
xlc myprogram.c -qinfo=all -qinfo=nocnv:norea
仅限 C以下示例显示了当代码编译时,编译器检测到 -qinfo=cnd:eff:got:obs:par:pro:rea:ret:uni 生效时的代码结构:
#define COND 0  

void faa() // Obsolete prototype (-qinfo=obs) 
{   
   printf("In faa\n"); // Unprototyped function call (-qinfo=pro) 
}  

int foo(int i, int k)  
{
   int j; // Uninitialized variable (-qinfo=uni)    

   switch(i) {   
   case 0:     
   i++;     
   if (COND) // Condition is always false (-qinfo=cnd)       
      i--;   // Unreachable statement (-qinfo=rea)     
   break;    

   case 1:     
      break;     
      i++;   // Unreachable statement (-qinfo=rea)   
   default:     
      k = (i) ? (j) ? j : i : 0;   
}   

   goto L;   // Use of goto statement (-qinfo=got)   
   return 3; // Unreachable statement (-qinfo=rea) 
L:   
   faa(); // faa() does not have a prototype (-qinfo=pro)   
 
// End of the function may be reached without returning a value   
// because of there may be a jump to label L (-qinfo=ret) 

} //Parameter k is never referenced (-qinfo=ref)   

int main(void) {   
({ int i = 0; i = i + 1; i; }); // Statement does not have side effects (-qinfo=eff)   

 return foo(1,2); 
} 
仅限 C + +以下示例显示了编译器检测到的代码结构,此代码在 -qinfo=cls:cnd:eff:use 生效的情况下编译:
#pragma abc       // pragma not supported (-qinfo=eff or -qinfo=gen)  

int bar() __attribute__((xyz));    // attribute not supported (-qinfo=eff) 
int j();  

class A {         
   public:
      A():  x(0), y(0), z(0) { };  // this constructor is in the correct order 
                                   // hence, no info message.                 
      A(int m): y(0), z(0)                     
      { x=m; };            // suggest using member initialization list
                              for x (-qinfo=cls)

      A(int m, int n):
      x(0), z(0) { };       // not all data members are initialized    
                            // namely, y is not initialized (-qinfo=cls)

      A(int m, int n, int* l):
      x(m), z(l), y(n) { };       // order of class initialization (-qinfo=cls)  

    private:                 
      int x;                 
      int y;                 
      int *z;      // suggest having user-defined copy constructor/   
                   // assignment operator to handle the pointer data member
                   // (-qinfo=cls) 
};  

int foo() {         
   int j=5;         
   j;        // null statement (-qinfo=eff)            
             // The user may mean to call j().         

return j; 

}  

void boo() {         
   int x;         
   int *i = &x;         
   float *f;            // f is not used (-qinfo=use)         
   f = (float *) i;     // incompatible type (-qinfo=eff)   
                        // With ansi aliasing mode, a float pointer 
                        // is not supposed to point to an int 
}  

void cond(int y) {         
   const int i=0;         
   int j;         
   int k=0;          
   
   if (i) {       // condition is always false (-qinfo=cnd)   
            j=3;         
    }          

   if (1) {       // condition is always true  (-qinfo=cnd) 
            j=4;        
          }         
   
   j=0;         
   if (j==0) {     // cond. is always true  (-qinfo=cnd) 
       j=5;         
   }                  

   if (y) {               
          k+=5
          }          

   if (k==5) {     // This case cannot be determined, because k+=5 
                   // is in a conditional block.  
              j=6;         
              } 
}  
在以下示例中,前面的 #pragma info (eff , nouni) 伪指令 MyFunction1 指示编译器生成用于标识语句或编译指示的消息而不起作用,并禁止用于标识未初始化的变量的消息。 MyFunction2 之前的 #pragma info (restore) 伪指令指示编译器复原在指定 #pragma info (eff , nouni) 伪指令之前生效的消息选项。
#pragma info(eff, nouni) 
int MyFunction1()
{
  .
  .
  .

}

#pragma info(restore)
int MyFunction2()
{
  .
  .
  .

}
以下示例显示了对别名判别违例的有效诊断:

t1.c:
int main() {
  short s = 42;
  int *pi = (int*) &s;
  *pi = 63;
  return 0;
}  
xlC -qinfo=als t1.c
"t1.c", line 4.3: 1540-0590 (I) Dereference may not conform to the current 
                                aliasing rules.
"t1.c", line 4.3: 1540-0591 (I) The dereferenced expression has type "int". 
                                "pi" may point to "s" which has incompatible 
                                type "short".
"t1.c", line 4.3: 1540-0592 (I) Check assignment at line 3 column 11 of t1.c.
在下面的示例中,分析不区分上下文,即两次调用 floatToInt 的行为没有区别。 此示例中不存在别名判别违例,但仍会发出诊断。
t2.c:
int* floatToInt(float *pf) { return (int*)pf; }

int main() {
  int i;
  float f;
   int* pi = floatToInt((float*)*&i));
   floatToInt(&f;)
   return *pi;
}  

xlC -qinfo=als t2.c
"t2.c", line 8.10: 1540-0590 (I) Dereference may not conform to the current
                                 aliasing rules.
"t2.c", line 8.10: 1540-0591 (I) The dereferenced expression has type "int".
                                 "pi" may point to "f" 
                                 which has incompatible type "float".
"t2.c", line 8.10: 1540-0592 (I) Check assignment at line 7 column 14 of t2.c.
"t2.c", line 8.10: 1540-0592 (I) Check assignment at line 1 column 37 of t2.c.
"t2.c", line 8.10: 1540-0592 (I) Check assignment at line 6 column 11 of t2.c.
t3.c:
int main() {
  float f;
  int i = 42;
  int *p = (int*) &f;
  p = &i;
  return *p;
}

xlC -qinfo=als t3.c
"t3.c", line 6.10: 1540-0590 (I) Dereference may not conform to
        the current aliasing rules.
"t3.c", line 6.10: 1540-0591 (I) The dereferenced expression has 
        type "int". "p" may point to "f", which has incompatible 
        type "float".
"t3.c", line 6.10: 1540-0592 (I) Check assignment at line 4 column 
        10 of t3.c.
要编译 sync.c 以生成有关并行代码中潜在同步问题的参考消息,请输入以下命令:
 xlc_r -O3 -qinfo=mt sync.c
假设 sync.c 包含以下代码:
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>

volatile int done;         /* shared flag */
volatile int result;       /* shared result */

void *setter(void *id) 
{
  sleep(5);
  result = 7;
  /* Need __lwsync(); */
  done = 1;                /* line 13 */
}

void *waiter(void *id) 
{
  while (!done)            /* line 18 */
  {
    sleep(1);
  }
  /* need __lwsync(); */
  printf("%d\n", result);
}

int main() 
{
  pthread_t threads[2];
  pthread_attr_t attr;
  int result;
  
  result = pthread_create(&threads[0], NULL, waiter, NULL);
  if (result != 0) exit(2);
  result = pthread_create(&threads[1], NULL, setter, NULL);  
  if (result != 0) exit(3);  
  
  pthread_join(threads[0], NULL); 
  pthread_join(threads[1], NULL);
  
  return 0;
}
编译器发出以下参考消息:
1586-669 (I) "sync.c", line 18: If this loop is used as a synchronization
point, additional synchronization via a directive or built-in function might
be needed.

1586-670 (I) "sync.c", line 13: If this statement is used as a synchronization
point, additional synchronization via a directive or built-in function might
be needed.
仅限 C 以下函数 部分初始化数组。 ini.c a[3] 要编译 ini.c 以生成有关此问题的参考消息,请输入以下命令:
xlc -qinfo=ini ini.c -c
假设 ini.c 包含以下代码:
int a[3] = {1};
编译器发出以下参考消息:
"ini.c", line 1.10: 1506-446 (I) Array element(s) [1] ... 
[2] will be initialized with a default value of 0.
仅限 C

相关信息