GVKun编程网logo

编译器的行为与通用方法的null参数不同(编译器常用语法分析方法)

29

在这里,我们将给大家分享关于编译器的行为与通用方法的null参数不同的知识,让您更了解编译器常用语法分析方法的本质,同时也会涉及到如何更有效地不起作用\给出了错误的输出为什么putchar()在wh

在这里,我们将给大家分享关于编译器的行为与通用方法的null参数不同的知识,让您更了解编译器常用语法分析方法的本质,同时也会涉及到如何更有效地 不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?、AngularJS then()的行为与success()不同 – error()、arm-linux-gcc 常用参数讲解 gcc编译器使用方法、arm三大编译器的不同选择编译的内容。

本文目录一览:

编译器的行为与通用方法的null参数不同(编译器常用语法分析方法)

编译器的行为与通用方法的null参数不同(编译器常用语法分析方法)

以下代码可以在Eclipse上完美编译,但是无法通过javac进行编译:

public class HowBizarre {      public static <P extends Number, T extends P> void doIt(P value) {      }      public static void main(String[] args) {            doIt(null);      }}

我简化了代码,所以现在根本不使用T。不过,我看不出发生此错误的原因。由于某种原因,javac决定T代表Object,然后抱怨Object不符合T的界限(这是对的):

HowBizarre.java:6:不兼容的类型;推断的类型实参java.lang.Number,java.lang.Object不符合类型变量P,T的范围

发现:<P,T>无效

必需:无效

       doIt(null);           ^

请注意,如果我将null参数替换为非null值,则可以正常编译。

哪个编译器行为正确,为什么?这是其中之一的错误吗?

答案1

小编典典

该问题是由于JLS规范所致,该规范要求必须将不可推论的类型参数推导为Object,即使它不满足界限(并因此会触发编译错误)。

以下是“错误”报告的摘录(为清楚起见,已对其进行了进一步注释):

[“错误” ID 6299211-方法类型变量:推断为空

](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6299211)

该程序无法编译:

public class Try {    void m() {        java.util.Collections.max(null);    }}

状态 :已 关闭,不是缺陷。

评估这不是错误
。推理算法无法从参数(null)收集任何信息,并且不会在对返回值有任何期望的地方调用该方法。在这种情况下,编译器必须推断出java.lang.Object类型变量。


JLS
15.12.2.8推断未解决的类型参数

然后,还可以推断出尚未推断出的所有剩余类型变量 Object


但是,Object不是的子类型,Comparable<? superObject>因此不在声明的类型变量的范围内Collections.max

<T extends Object& Comparable<? super T>> T max(Collection<?extendsT>)


进一步的探索

使用显式类型参数可以“解决”问题:

HowBizarre.<Number,Integer>doIt(null); // compiles fine in javac

为了表明与null参数无关,而与类型推断的绝对缺乏信息更多,可以尝试例如以下两种声明之一:

<T,U extends Comparable<T>> void doIt()<T extends Number,U extends T> void doIt()

在这两种情况下,调用doIt();都不会在中进行编译javac,因为它必须推断U为符合Object15.12.2.8,即使这样做会触发编译错误。


关于Eclipse的注意

尽管以上代码片段均未​​在的某些版本中进行编译javac,但它们都在Eclipse的某些版本中进行了编译。这可能暗示了Eclipse的错误。众所周知,不同的编译器之间存在分歧。

 不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?

 不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?

如何解决\b 不起作用 \\ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同??

1-10。编写一个程序将其输入复制到其输出,用 \t 替换每个制表符,每个制表符 \b 退格,每个反斜杠 \。这使得制表符和退格在 明确的方式。

我试着写了几次。这是我想出来的。

#include <stdio.h>
main()
{
    int i ;
    while ((i = getchar())!= EOF){
        if (i == ''\t''){
            putchar(''\\'');
            putchar(''t'');
        }
        if (i == ''\b''){
            putchar(''\\'');
            putchar(''b'');
        }
        if (i == ''\\''){
            //putchar(''\\'');
            putchar(''\\'');
        }
        if (i != ''\t''){
        putchar(i);
        }
    }
}

你一定注意到我已经注释掉了第三个 if 子句中的 putchar。 我有三个问题。

  1. ''\b'' 字符根本不起作用。我找不到任何打印出“\b”的可能性。如何 去做吗?

  2. 第三个 if 子句中的 putchar 打印三倍的反斜杠。当被注释掉时, 它打印 2 次(根据问题的需要)。为什么..?

  3. 在第 4 个 if 子句中,putchar 工作正常。但是一旦我从 if 子句中取出它 将其打印到 While Scope(这是我的第一次尝试)。 它打印出 ''\t'' 加上实际的制表符空间然后在下一个字符之后??

为什么会这样..?是什么原因..?

//if (i != ''\t''){    
            putchar(i); -> this is inside the while scope.
            //}
output:
test*tab*this. (executing getchar)
test\t    this (executing putchar)

PS - 我不能使用 else 子句。或上述以外的任何内容。我还没有达到 else 或在书中继续。因此,我故意避免使用 else。

解决方法

没有 elsecontinue,使用辅助变量

#include <stdio.h>

int main(void) {
    int i;
    while ((i = getchar()) != EOF) {
        int processed = 0;
        if (i == ''\t'') {
            putchar(''\\'');
            putchar(''t'');
            processed = 1;
        }
        if (i == ''\b'') {
            putchar(''\\'');
            putchar(''b'');
            processed = 1;
        }
        if (i == ''\\'') {
            putchar(''\\'');
            putchar(''\\'');
            processed = 1;
        }
        if (!processed) putchar(i);
    }
    return 0;
}

$ echo -e ''backslash [\\]\ntab [\t]\nback [\b]''
backslash [\]
tab [   ]
back ]

$ echo -e ''backslash [\\]\ntab [\t]\nback [\b]'' | ./a.out
backslash [\\]
tab [\t]
back [\b]

AngularJS then()的行为与success()不同 – error()

AngularJS then()的行为与success()不同 – error()

参见英文答案 > Why are AngularJS $http success/error methods deprecated? Removed from v1.6?2个
由于在AngularJS中不推荐使用success()和error()函数,我正在更新我的代码,用then()替换它们.现在根据我的理解,这两段代码的行为应该相同:
$http
   .get(/* some params */)
   .success(function() {
      // success cases here
   })
   .error(function() {
      // error cases here
   });

$http
   .get(/* some params */)
   .then(function() {
      // success cases here
   },function() {
      // error cases here
   });

但在某些情况下,我会得到不同的行为.你能否向我解释为什么会发生这种情况,更重要的是,使用then()函数保证相同行为的方法是什么?

.success和.error方法忽略返回值.
因此它们不适合链接.
var httpPromise = $http
       .get(/* some params */)
       .success(function onSuccess(data,status,headers,config) {
          var modifiedData = doModify(data);
          //return value ignored
          return modifiedData;
       })
       .error(function onError(data,config) {
          // error cases here
       });

httpPromise.then(function onFullfilled(response) {
    //chained data lost
    //instead there is a response object
    console.log(response.data); //original data
    console.log(response.status); //original status
});

另一方面,.then和.catch方法返回一个派生的promise,适用于从返回(或抛出)值或新promise中链接.

var derivedPromise = $http
       .get(/* some params */)
       .then(function onFulfilled(response) {
          console.log(response.data); //original data
          console.log(response.status); //original status

          var modifiedData = doModify(response.data);
          //return a value for chaining
          return modifiedData;
       })
       .catch(function onRejected(response) {
          // error cases here
       });

derivedPromise.then(function onFullfilled(modifiedData) {
    //data from chaining
    console.log(modifiedData);
});

响应对象与四个参数

另请注意,$http服务在调用提供给.success和.error方法的函数时提供了四个参数(data,config).

$q服务仅为提供给.then或.catch方法的函数提供一个参数(响应).对于由$http服务创建的promises,响应对象具有以下属性:1

> data – {string | Object} – 使用转换函数转换的响应体.
> status – {number} – 响应的HTTP状态代码.
> headers – {function([headerName])} – 标头getter函数.
> config – {Object} – 用于生成请求的配置对象.
> statusText – {string} – 响应的HTTP状态文本.

Chaining promises

Because calling the then method of a promise returns a new derived promise,it is easily possible to create a chain of promises. It is possible to create chains of any length and since a promise can be resolved with another promise (which will defer its resolution further),it is possible to pause/defer resolution of the promises at any point in the chain. This makes it possible to implement powerful APIs.07001

更新

.enccess和.error方法已被弃用并从AngularJS V1.6中删除.

有关更多信息,请参阅

> Why are angular $http success/error methods deprecated? Removed from v1.6?

arm-linux-gcc 常用参数讲解 gcc编译器使用方法

arm-linux-gcc 常用参数讲解 gcc编译器使用方法

arm-linux-gcc 常用参数讲解 gcc编译器使用方法

我们需要编译出运行在ARM平台上的代码,所 使用的交叉编译器为  arm-linux-gcc。下面将 arm-linux-gcc编译工具的一些常用命令参数介绍给大家。
在此之前首先介绍下编译器的工作过程,在 使用GCC编译程序时,编译过程分为四个阶段:
1. 预处理(Pre-Processing)
2. 编译(Compiling)
3. 汇编(Assembling)
4. 链接(Linking)
Linux程序员可以根据自己的需要让 GCC在编译的任何阶段结束,以便检查或 使用编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为 今后的调试做好准备。和其它常用的编译器一样,GCC也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。

以文件example.c为例说明它的用法
0. arm-linux-gcc -o example example.c
   不加-c、-S、-E参数,编译器将执行预处理、编译、汇编、连接操作直接生成可执行代码。
    -o参数用于指定输出的文件,输出文件名为example,如果不指定输出文件,则默认输出a.out

1. arm-linux-gcc -c -o example.o example.c
   -c参数将对源程序example.c进行预处理、编译、汇编操作,生成example.o文件
   去掉指定输出选项"-o example.o"自动输出为example.o,所以说在这里-o加不加都可以

2.arm-linux-gcc -S -o example.s example.c
   -S参数将对源程序example.c进行预处理、编译,生成example.s文件
   -o选项同上

3.arm-linux-gcc -E -o example.i example.c
   -E参数将对源程序example.c进行预处理,生成example.i文件(不同版本不一样,有的将预处理后的内容打印到屏幕上)
   就是将#include,#define等进行文件插入及宏扩展等操作。
  
4.arm-linux-gcc -v -o example example.c
加上-v参数,显示编译时的详细信息,编译器的版本,编译过程等。

5.arm-linux-gcc -g -o example example.c
-g选项,加入GDB能够使用的调试信息,使用GDB调试时比较方便。

6.arm-linux-gcc -Wall -o example example.c
-Wall选项打开了所有需要注意的警告信息,像在声明之前就使用的函数,声明后却没有使用的变量等。

7.arm-linux-gcc -Ox -o example example.c
-Ox使用优化选项,X的值为空、0、1、2、3
0为不优化,优化的目的是减少代码空间和提高执行效率等,但相应的编译过程时间将较长并占用较大的内存空间。

8.arm-linux-gcc   -I /home/include -o example example.c
-Idirname: 将dirname所指出的目录加入到程序头文件目录列表中。如果在预设系统及当前目录中没有找到需要的文件,就到指定的dirname目录中去寻找。

9.arm-linux-gcc   -L /home/lib -o example example.c

-Ldirname:将dirname所指出的目录加入到库文件的目录列表中。在默认状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的库文件,这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后再到系统预设路径中寻找。

10.arm-linux-gcc –static -o libexample.a example.c

静态链接库文件

 

gcc在命令行上经常使用的几个选项是:
-c   只预处理、编译和汇编源程序,不进行连接。编译器对每一个源程序产生一个目标文件。

-o file  确定输出文件为file。如果没有用-o选项,缺省的可执行文件的输出是a.out,目标文件和汇编文件的输出对source.suffix分别是source.o和source.s,预处理的C源程序的输出是标准输出stdout。

-Dmacro 或-Dmacro=defn   其作用类似于源程序里的#define。例如:% gcc -c -DHAVE_GDBM -DHELP_FILE=\"help\" cdict.c其中第一个- D选项定义宏HAVE_GDBM,在程序里可以用#ifdef去检查它是否被设置。第二个-D选项将宏HELP_FILE定义为字符串“help”(由于 反斜线的作用,引号实际上已成为该宏定义的一部分),这对于控制程序打开哪个文件是很有用的。

-Umacro   某些宏是被编译程序自动定义的。这些宏通常可以指定在其中进行编译的计算机系统类型的符号,用户可以在编译某程序时加上 -v选项以查看gcc缺省定义了哪些宏。如果用户想取消其中某个宏定义,用-Umacro选项,这相当于把#undef macro放在要编译的源文件的开头。

-Idir   将dir目录加到搜寻头文件的目录列表中去,并优先于在gcc缺省的搜索目录。在有多个-I选项的情况下,按命令行上-I选项的前后顺序搜索。dir可使用相对路径,如-I../inc等。

-O   对程序编译进行优化,编译程序试图减少被编译程序的长度和执行时间,但其编译速度比不做优化慢,而且要求较多的内存。

-O2   允许比-O更好的优化,编译速度较慢,但结果程序的执行速度较快。

-g   产生一张用于调试和排错的扩展符号表。-g选项使程序可以用GNU的调试程序GDB进行调试。优化和调试通常不兼容,同时使用-g和-O(-O2)选项经常会使程序产生奇怪的运行结果。所以不要同时使用-g和-O(-O2)选项。

-fpic或-fPIC   产生位置无关的目标代码,可用于构造共享函数库。

以 上是gcc的编译选项。gcc的命令行上还可以使用连接选项。事实上,gcc将所有不能识别的选项传递给连接程序ld。连接程序ld将几个目标文件和库程 序组合成一个可执行文件,它要解决对外部变量、外部过程、库程序等的引用。但我们永远不必要显式地调用ld。利用gcc命令去连接各个文件是很简单的,即 使在命令行里没有列出库程序,gcc也能保证某些库程序以正确的次序出现。

gcc的常用连接选项有下列几个:
-Ldir   将dir目录加到搜寻-l选项指定的函数库文件的目录列表中去,并优先于gcc缺省的搜索目录。在有多个-L选项的情况下,按命令行上-L选项的前后顺序搜索。dir可使用相对路径。如-L../lib等。

-lname   在连接时使用函数库libname.a,连接程序在-Ldir选项指定的目录下和/lib,/usr/lib目录下寻找该库文件。在没有使用-static选项时,如果发现共享函数库libname.so,则使用libname.so进行动态连接。

-static   禁止与共享函数库连接。

-shared   尽量与共享函数库连接

arm三大编译器的不同选择编译

arm三大编译器的不同选择编译

ARM 系列目前支持三大主流的工具链,即ARM RealView (armcc), IAR EWARM (iccarm), and GNU Compiler Collection (gcc). 

   在core_cm3.h中有如下定义:
     /* define compiler specific symbols */
  #if defined ( __CC_ARM )
     #define __ASM __asm /*!< asm keyword for armcc */
     #define __INLINE __inline /*!< inline keyword for armcc */
 #elif defined ( __ICCARM__ )
     #define __ASM __asm /*!< asm keyword for iarcc */
     #define __INLINE inline /*!< inline keyword for iarcc. Only
                                   avaiable in High optimization mode! */
     #define __nop __no_operation /*!< no operation intrinsic in iarcc */
 #elif defined ( __GNUC__ )
     #define __ASM asm /*!< asm keyword for gcc */
     #define __INLINE inline /*!< inline keyword for gcc
 #endif 

关于编译器的行为与通用方法的null参数不同编译器常用语法分析方法的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于 不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?、AngularJS then()的行为与success()不同 – error()、arm-linux-gcc 常用参数讲解 gcc编译器使用方法、arm三大编译器的不同选择编译的相关知识,请在本站寻找。

本文标签: