- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我想编写一些接受字符串文字的函数 - 和 只有字符串文字:
template <size_t N>
void foo(const char (&str)[N]);
char
数组。 - 是否是真正的字符串文字。虽然在编译时无法区分它们之间的区别 -
没有 不得不要求调用者包装文字/数组 - 在运行时,这两个数组将在内存中完全不同的位置:
foo("Hello"); // at 0x400f81
const char msg[] = {'1', '2', '3'};
foo(msg); // at 0x7fff3552767f
assert
该函数仅采用字符串文字吗? (使用 gcc 4.7.3,但对于任何编译器来说,真正的解决方案都会很棒)。
最佳答案
您似乎认为“真正的字符串文字”的必要特征
是编译器将其烘焙到可执行文件的静态存储中。
这实际上不是真的。 C 和 C++ 标准向我们保证
字符串文字应具有静态存储持续时间,因此它必须存在于
程序的生命周期,但如果编译器可以在不放置的情况下安排它
静态存储中的文字,它是自由的,有时有些编译器
做。
但是,很明显,对于给定的字符串,您要测试的属性
字面意思,就是是否真的在静态存储中。因为它不需要
在静态存储中,只要语言标准保证,有
不能完全基于可移植 C/C++ 解决您的问题。
给定的字符串文字实际上是否在静态存储中是个问题
字符串文字的地址是否位于
分配给符合条件的链接部分的地址范围
静态存储,在您的特定工具链的命名中,当
您的程序是由该工具链构建的。
所以我建议的解决方案是让你的程序知道
符合条件的自身链接部分的地址范围
静态存储,然后它可以测试给定的字符串文字是否
通过明显的代码在静态存储中。
这是玩具 C++ 项目的此解决方案的说明,prog
使用 GNU/Linux x86_64 工具链构建(C++98 或更高版本即可,并且
C 的方法只是稍微复杂一点)。在此设置中,我们在 ELF 中链接
格式,我们认为静态存储的链接部分是 .bss
(0-初始化静态数据),.rodata
(只读静态静态)和 .data
(读/写静态数据)。
以下是我们的源文件:
section_bounds.h
#ifndef SECTION_BOUNDS_H
#define SECTION_BOUNDS_H
// Export delimiting values for our `.bss`, `.rodata` and `.data` sections
extern unsigned long const section_bss_start;
extern unsigned long const section_bss_size;
extern unsigned long const section_bss_end;
extern unsigned long const section_rodata_start;
extern unsigned long const section_rodata_size;
extern unsigned long const section_rodata_end;
extern unsigned long const section_data_start;
extern unsigned long const section_data_size;
extern unsigned long const section_data_end;
#endif
// Assign either placeholder or pre-defined values to
// the section delimiting globals.
#ifndef BSS_START
#define BSS_START 0x0
#endif
#ifndef BSS_SIZE
#define BSS_SIZE 0xffff
#endif
#ifndef RODATA_START
#define RODATA_START 0x0
#endif
#ifndef RODATA_SIZE
#define RODATA_SIZE 0xffff
#endif
#ifndef DATA_START
#define DATA_START 0x0
#endif
#ifndef DATA_SIZE
#define DATA_SIZE 0xffff
#endif
extern unsigned long const
section_bss_start = BSS_START;
extern unsigned long const section_bss_size = BSS_SIZE;
extern unsigned long const
section_bss_end = section_bss_start + section_bss_size;
extern unsigned long const
section_rodata_start = RODATA_START;
extern unsigned long const
section_rodata_size = RODATA_SIZE;
extern unsigned long const
section_rodata_end = section_rodata_start + section_rodata_size;
extern unsigned long const
section_data_start = DATA_START;
extern unsigned long const
section_data_size = DATA_SIZE;
extern unsigned long const
section_data_end = section_data_start + section_data_size;
#ifndef CSTR_STORAGE_TRIAGE_H
#define CSTR_STORAGE_TRIAGE_H
// Classify the storage type addressed by `s` and print it on `cout`
extern void cstr_storage_triage(const char *s);
#endif
#include "cstr_storage_triage.h"
#include "section_bounds.h"
#include <iostream>
using namespace std;
void cstr_storage_triage(const char *s)
{
unsigned long addr = (unsigned long)s;
cout << "When s = " << (void*)s << " -> \"" << s << '\"' << endl;
if (addr >= section_bss_start && addr < section_bss_end) {
cout << "then s is in static 0-initialized data\n";
} else if (addr >= section_rodata_start && addr < section_rodata_end) {
cout << "then s is in static read-only data\n";
} else if (addr >= section_data_start && addr < section_data_end){
cout << "then s is in static read/write data\n";
} else {
cout << "then s is on the stack/heap\n";
}
}
// Demonstrate storage classification of various arrays of char
#include "cstr_storage_triage.h"
static char in_bss[1];
static char const * in_rodata = "In static read-only data";
static char in_rwdata[] = "In static read/write data";
int main()
{
char on_stack[] = "On stack";
cstr_storage_triage(in_bss);
cstr_storage_triage(in_rodata);
cstr_storage_triage(in_rwdata);
cstr_storage_triage(on_stack);
cstr_storage_triage("Where am I?");
return 0;
}
.PHONY: all clean
SRCS = main.cpp cstr_storage_triage.cpp section_bounds.cpp
OBJS = $(SRCS:.cpp=.o)
TARG = prog
MAP_FILE = $(TARG).map
ifdef AGAIN
BSS_BOUNDS := $(shell grep -m 1 '^\.bss ' $(MAP_FILE))
BSS_START := $(word 2,$(BSS_BOUNDS))
BSS_SIZE := $(word 3,$(BSS_BOUNDS))
RODATA_BOUNDS := $(shell grep -m 1 '^\.rodata ' $(MAP_FILE))
RODATA_START := $(word 2,$(RODATA_BOUNDS))
RODATA_SIZE := $(word 3,$(RODATA_BOUNDS))
DATA_BOUNDS := $(shell grep -m 1 '^\.data ' $(MAP_FILE))
DATA_START := $(word 2,$(DATA_BOUNDS))
DATA_SIZE := $(word 3,$(DATA_BOUNDS))
CPPFLAGS += \
-DBSS_START=$(BSS_START) \
-DBSS_SIZE=$(BSS_SIZE) \
-DRODATA_START=$(RODATA_START) \
-DRODATA_SIZE=$(RODATA_SIZE) \
-DDATA_START=$(DATA_START) \
-DDATA_SIZE=$(DATA_SIZE)
endif
all: $(TARG)
clean:
rm -f $(OBJS) $(MAP_FILE) $(TARG)
ifndef AGAIN
$(MAP_FILE): $(OBJS)
g++ -o $(TARG) $(CXXFLAGS) -Wl,-Map=$@ $(OBJS) $(LDLIBS)
touch section_bounds.cpp
$(TARG): $(MAP_FILE)
$(MAKE) AGAIN=1
else
$(TARG): $(OBJS)
g++ -o $@ $(CXXFLAGS) $(OBJS) $(LDLIBS)
endif
make
好像:
$ make
g++ -c -o main.o main.cpp
g++ -c -o cstr_storage_triage.o cstr_storage_triage.cpp
g++ -c -o section_bounds.o section_bounds.cpp
g++ -o prog -Wl,-Map=prog.map main.o cstr_storage_triage.o section_bounds.o
touch section_bounds.cpp
make AGAIN=1
make[1]: Entering directory `/home/imk/develop/SO/string_lit_only'
g++ -DBSS_START=0x00000000006020c0 -DBSS_SIZE=0x118 -DRODATA_START=0x0000000000400bf0
-DRODATA_SIZE=0x120 -DDATA_START=0x0000000000602070 -DDATA_SIZE=0x3a
-c -o section_bounds.o section_bounds.cpp
g++ -o prog main.o cstr_storage_triage.o section_bounds.o
prog
做:
$ ./prog
When s = 0x6021d1 -> ""
then s is in static 0-initialized data
When s = 0x400bf4 -> "In static read-only data"
then s is in static read-only data
When s = 0x602090 -> "In static read/write data"
then s is in static read/write data
When s = 0x7fffa1b053a0 -> "On stack"
then s is on the stack/heap
When s = 0x400c0d -> "Where am I?"
then s is in static read-only data
section_*
应该保存这些值的变量
make
运行,食谱:
$(TARG): $(MAP_FILE)
$(MAKE) AGAIN=1
$(MAP_FILE): $(OBJS)
g++ -o $(TARG) $(CXXFLAGS) -Wl,-Map=$@ $(OBJS) $(LDLIBS)
touch section_bounds.cpp
AGAIN
未定义。他们告诉
make
为了
prog
它必须首先构建
prog
的链接器映射文件, 按照
section_bounds.cpp
.在那之后,
make
是再次调用自己,用
AGAIN
定义 = 1。
AGAIN
定义,
make
现在发现它
BSS_BOUNDS
BSS_START
BSS_SIZE
RODATA_BOUNDS
RODATA_START
RODATA_SIZE
DATA_BOUNDS
DATA_START
DATA_SIZE
S
,它计算
S_BOUNDS
通过搜索
S
的地址和大小的行的链接器映射文件.
S_START
,
S_SIZE
.所有部分
-D
附加定界值
CPPFLAGS
的选项
AGAIN
已定义,
$(TARG)
的操作配方现在是惯例:
$(TARG): $(OBJS)
g++ -o $@ $(CXXFLAGS) $(OBJS) $(LDLIBS)
section_bounds.cpp
在父级
make
;所以它必须是
prog
必须重新链接。这一次,当
section_bounds.cpp
编译后,所有节分隔宏:
BSS_START
BSS_SIZE
RODATA_START
RODATA_SIZE
DATA_START
DATA_SIZE
关于c++ - 区分字符串文字和字符数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28437613/
如何使用 SPListCollection.Add(String, String, String, String, Int32, String, SPListTemplate.QuickLaunchO
我刚刚开始使用 C++ 并且对 C# 有一些经验,所以我有一些一般的编程经验。然而,似乎我马上就被击落了。我试过在谷歌上寻找,以免浪费任何人的时间,但没有结果。 int main(int argc,
这个问题已经有答案了: In Java 8 how do I transform a Map to another Map using a lambda? (8 个回答) Convert a Map>
我正在使用 node + typescript 和集成的 swagger 进行 API 调用。我 Swagger 提出以下要求 http://localhost:3033/employees/sear
我是 C++ 容器模板的新手。我收集了一些记录。每条记录都有一个唯一的名称,以及一个字段/值对列表。将按名称访问记录。字段/值对的顺序很重要。因此我设计如下: typedef string
我需要这两种方法,但j2me没有,我找到了一个replaceall();但这是 replaceall(string,string,string); 第二个方法是SringBuffer但在j2me中它没
If string is an alias of String in the .net framework为什么会发生这种情况,我应该如何解释它: type JustAString = string
我有两个列表(或字符串):一个大,另一个小。 我想检查较大的(A)是否包含小的(B)。 我的期望如下: 案例 1. B 是 A 的子集 A = [1,2,3] B = [1,2] contains(A
我有一个似乎无法解决的小问题。 这里...我有一个像这样创建的输入... var input = $(''); 如果我这样做......一切都很好 $(this).append(input); 如果我
我有以下代码片段 string[] lines = objects.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.No
这可能真的很简单,但我已经坚持了一段时间了。 我正在尝试输出一个字符串,然后输出一个带有两位小数的 double ,后跟另一个字符串,这是我的代码。 System.out.printf("成本:%.2
以下是 Cloud Firestore 列表查询中的示例之一 citiesRef.where("state", ">=", "CA").where("state", "= 字符串,我们在Stack O
我正在尝试检查一个字符串是否包含在另一个字符串中。后面的代码非常简单。我怎样才能在 jquery 中做到这一点? function deleteRow(locName, locID) { if
这个问题在这里已经有了答案: How to implement big int in C++ (14 个答案) 关闭 9 年前。 我有 2 个字符串,都只包含数字。这些数字大于 uint64_t 的
我有一个带有自定义转换器的 Dozer 映射: com.xyz.Customer com.xyz.CustomerDAO customerName
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 6 年前。 我想了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是
我已阅读 this问题和其他一些问题。但它们与我的问题有些无关 对于 UILabel 如果你不指定 ? 或 ! 你会得到这样的错误: @IBOutlet property has non-option
这两种方法中哪一种在理论上更快,为什么? (指向字符串的指针必须是常量。) destination[count] 和 *destination++ 之间的确切区别是什么? destination[co
This question already has answers here: Closed 11 years ago. Possible Duplicates: Is String.Format a
我有一个Stream一个文件的,现在我想将相同的单词组合成 Map这很重要,这个词在 Stream 中出现的频率. 我知道我必须使用 collect(Collectors.groupingBy(..)
我是一名优秀的程序员,十分优秀!