我想知道为什么C,C++和Java中的静态变量默认初零归零?为什么局部变量不是这样呢?
假设我有一个简单的Login servlet,它检查传递name和创建User对象并将其存储在会话中.
User user = new User();
user.setId(name);
request.getSession().setAttribute("user", user);
response.sendRedirect("index.jsp");
Run Code Online (Sandbox Code Playgroud)
在index.jsp页面中,我通过访问用户对象jsp:useBean
<jsp:useBean id="user" scope="session"
class="package.name.User"/>
<div class="panel">
Welcome ${user.id}
</div>
Run Code Online (Sandbox Code Playgroud)
它到目前为止工作.
来自jsp beans文档
要找到或实例化Bean,请按以下顺序执行以下步骤:
- 尝试使用您指定的范围和名称查找Bean.
- 使用您指定的名称定义对象引用变量.
- 如果找到Bean,则在变量中存储对它的引用.如果指定了type,则为Bean提供类型.
- 如果找不到Bean,则从您指定的类中实例化它,在新变量中存储对它的引用.如果类名表示序列化模板,则Bean由java.beans.Beans.instantiate实例化.
- 如果已实例化(而不是定位)Bean,并且它具有正文标记或元素(在和之间),则执行body标记.
问题:
尝试使用您指定的范围和名称查找Bean
它没有指定"定位"过程.这是否意味着它会检查HttpServletRequest.getSession()或只是检查其他页面是否已经创建了这个bean?
如果找不到Bean,则从您指定的类中实例化它,在新变量中存储>引用它.
这实际上意味着Jsp可以使用jsp_internal_name_user将新创建的bean与会话相关联.没有关于Jsp如何在会话中存储和查找bean的消息.
有一个选项可以通过使用来访问会话对象${sessionScope.user},这将保证来自Java会话对象的"用户"将被获取.我自己投入的那个.
Java EE 5示例"Book Store"使用${sessionScope.name}方法访问会话对象.
使用只是${user}工作.这就是让我担心的问题.我希望在规范中看到关于locate进程的特定句子以及是否${user}必须工作或是否由JSP和/或JSTL参考实现决定.
我一直在寻找一种方法来检查可变参数宏参数列表是否为空。我发现所有解决方案似乎都非常复杂,或者使用了非标准扩展。
我想我找到了既紧凑又标准的简单解决方案:
#define is_empty(...) ( sizeof( (char[]){#__VA_ARGS__} ) == 1 )
Run Code Online (Sandbox Code Playgroud)
问:在任何情况下我的解决方案都会失败或调用定义不明确的行为吗?
基于C17 6.10.3.2/2(#运算符):“对应于一个空参数的字符串文字是""”,我相信它#__VA_ARGS__总是定义明确的。
宏说明:
"",它仅包含一个空终止符,因此大小为1。我知道C中的字符串只是字符数组。因此,我尝试了以下代码,但给出了奇怪的结果,例如垃圾输出或程序崩溃:
#include <stdio.h>
int main (void)
{
char str [5] = "hello";
puts(str);
}
Run Code Online (Sandbox Code Playgroud)
为什么不起作用?
它可以用干净地编译gcc -std=c17 -pedantic-errors -Wall -Wextra。
注意:对于在声明字符串时未能为NUL终止符分配空间而引起的问题,本帖子旨在用作规范的FAQ。
我需要测量名称以字符串形式提供的两个地方之间的物理距离.由于有时名称的写法略有不同,我正在寻找一个可以帮助我衡量差异的库,然后将其与纬度和经度的度量相结合,以选择正确的匹配.首选语言:Java或PHP.
有什么建议?
我已经读过传入的jmp_buf变量中的setjmp"保存程序状态",但是我还没有找到任何关于它究竟是什么的描述.它是否复制了所有应用程序的内存?只是寄存器?堆栈?
在严格别名方面,这段代码是明确定义的行为吗?
_Bool* array = malloc(n);
memset(array, 0xFF, n);
_Bool x = array[0];
Run Code Online (Sandbox Code Playgroud)
有效类型的规则具有memcpy和memmove(C176.5§6)的特殊情况,但不适用于memset.
我认为有效的类型就变成了unsigned char.因为第二个参数memset需要转换为unsigned char(C17 7.24.6.1)并且由于有效类型的规则,(C176.5§6):
...或者被复制为字符类型数组,然后该访问的修改对象的有效类型以及不修改该值的后续访问是从中复制值的对象的有效类型,如果它有一个.
array后存储的数据的有效类型是memset什么?array[0]访问是否违反了严格的别名?因为_Bool不是严格别名规则中排除的类型(与字符类型不同).为什么AsDouble1比 更简单AsDouble0?
// AsDouble0(unsigned long): # @AsDouble0(unsigned long)
// movq xmm1, rdi
// punpckldq xmm1, xmmword ptr [rip + .LCPI0_0] # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
// subpd xmm1, xmmword ptr [rip + .LCPI0_1]
// movapd xmm0, xmm1
// unpckhpd xmm0, xmm1 # xmm0 = xmm0[1],xmm1[1]
// addsd xmm0, xmm1
// addsd xmm0, xmm0
// ret
double AsDouble0(uint64_t x) { return x * 2.0; }
// AsDouble1(unsigned long): # @AsDouble1(unsigned long)
// shr rdi
// cvtsi2sd xmm0, rdi …Run Code Online (Sandbox Code Playgroud) 我正在执行这个问题的代码:为什么以下代码的输出不为零?
#include <stdio.h>
int main (void)
{
double A = 373737.0;
double B;
B = A*A*A + 0.37/A - A*A*A - 0.37/A;
printf("The value of B is %f.\n", B);
}
Run Code Online (Sandbox Code Playgroud)
每个主流 x86 编译器的每个优化设置都会给出输出-0.000001。当我使用当前的 clang 15.0.0 时,我-O0也得到了这一点。
但是,使用 14.0.0 版本以上的 clang 和-O1to进行编译-O3会给出输出-1.000001。为什么会发生这种情况?这是一个已知的错误?
Godbolt 为了您的方便:https ://godbolt.org/z/M5j3fGhWf
我正在讨论使用具有不确定值的变量导致未指定的行为,而不是未定义的行为,如此处所述。这假设具有自动存储持续时间的变量已获取其地址并且陷阱表示不适用。
在具体情况下,讨论了ptr之后发生的情况free(ptr),在这种情况下 C17 6.2.4 适用:
当指针指向(或刚刚过去)的对象到达其生命周期结束时,指针的值变得不确定。
我做了这个例子:
#include <stdlib.h>
#include <stdio.h>
int main (void)
{
int* ptr = malloc(sizeof *ptr);
int* garbage;
int*volatile* dummy = &garbage; // take the address
free(ptr);
puts("This should always print");
fflush(stdout);
if(ptr == garbage)
{
puts("Didn't see that one coming.");
}
else
{
puts("I expect this to happen");
}
puts("This should always print");
}
Run Code Online (Sandbox Code Playgroud)
我提出的论点是,从理论上讲,我们无法知道是ptr == garbage真是假,因为此时它们都是不确定的。因此编译器甚至不需要读取这些内存位置 - 因为它可以推断两个指针都保存不确定的值,所以在优化期间可以根据需要自由地将表达式评估为 true 或 false。(实际上大多数编译器可能不会这样做。)
我在 x86_64 编译器 …