NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
Мое кросс-платформенное решение при первом запуске CMake создает файл timestamp.cmake
в двоичном каталоге и определяет цель timestamp
, которая запускает сгенерированный файл. Файл timestamp.cmake
формирует строку штампа ISO 8601 с использованием команды STRING
CMake и записывает ее в файл timestamp.h
с предваряющей директивой #define _TIMEZ_
preprocessor preended (определяет с одним ведущим подчеркиванием в порядке, определяет с двумя ведущими подчеркиваниями не должен быть определен пользователем).
Включите следующее в основной файл CMake.
# build time in UTC ISO 8601
FILE (WRITE ${CMAKE_BINARY_DIR}/timestamp.cmake "STRING(TIMESTAMP TIMEZ UTC)\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(WRITE timestamp.h \"#ifndef TIMESTAMP_H\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define TIMESTAMP_H\\n\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#define _TIMEZ_ \\\"\${TIMEZ}\\\"\\n\\n\")\n")
FILE (APPEND ${CMAKE_BINARY_DIR}/timestamp.cmake "FILE(APPEND timestamp.h \"#endif // TIMESTAMP_H\\n\")\n")
ADD_CUSTOM_TARGET (
timestamp
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/timestamp.cmake
ADD_DEPENDENCIES ${CMAKE_BINARY_DIR}/timestamp.cmake)
Затем используйте команду ADD_DEPENDENCIES
CMake, чтобы сделать вашу основную цель (возможно, главный исполняемый файл), зависящий от цели timestamp
.
ADD_DEPENDENCIES (${CMAKE_BINARY_DIR}/${BINARY_NAME} timestamp)
Вы можете указать несколько дополнительных зависимостей, разделенных символом если вам нужно это сделать.
Тогда вы можете просто #include "timestamp.h"
(если предположить, что двоичный каталог CMake находится в включенном пути, который обычно есть. Если нет, это просто: INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR})
) и используйте _TIMEZ_
всякий раз, когда вы хотите иметь штамп времени сборки в формате ISO 8601 (или, фактически, что угодно: вы можете указать его самостоятельно, см. документацию CMake для использования команды STRING
).
Это могло быть упрощено непосредственно (вручную), создав файл timestamp.cmake
и добавив его в ваш репозиторий кода, но я счел его не чистым достаточно. Это общий недостаток CMake, который не может получить доступ к процедуре формирования строки штампа времени (той, которая используется в команде STRING
CMake) на этапе, где бэкэнд CMake, независимо от того, что он (например, GNU make) работает, поэтому нужно используйте отдельный файл CMake и вызовите его на этом этапе. Это можно было бы сделать намного проще и чище, если бы вы могли вызвать процедуру формирования строки штампа CMake в «режиме команд CMake» (тип вызова cmake -E
), например, например: cmake -E date [format] [UTC]
, но, увы , Я отправил билет в трекер Mathis для отслеживания ошибок Mateis .
Вы можете помочь, чтобы это произошло, поддерживая мой запрос функции, размещая некоторые комментарии, показывающие, сколько вам нужно на этом.
Возможно, вы могли бы использовать макросы компилятора __DATE__
__TIME__
внутри своего кода, а не получать его из cmake. Стоит упомянуть, что вам нужно будет очистить / сделать, чтобы обновить эти значения (поскольку GCC внедряет его, если объект уже скомпилирован, он не будет компилироваться снова, поэтому нет изменения даты / времени)
Для относительно недавних версий CMake (> = 2.8.11):
string (TIMESTAMP {output variable} [{format string}] [UTC])
(см. [д0] http://www.cmake.org/cmake/help/v3.0/command/string.html [/ д0]). Например, STRING (TIMESTAMP TODAY "% Y% m% d")
string(TIMESTAMP ...
кэшируется до тех пор, пока вы не отредактируете CMakeLists.txt
– Orient
14 June 2018 в 13:11
Я получаю следующее решение:
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
add_custom_target(
"linktimestamp"
ALL
COMMAND date +'%Y-%m-%d %H:%M:%S' > "linktimestamp.txt"
COMMAND objcopy --input binary --output elf64-x86-64 --binary-architecture i386:x86-64 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA "linktimestamp.txt" "linktimestamp.o"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "link timestamp: ${LINK_TIMESTAMP}"
)
else()
add_custom_target(
"linktimestamp"
ALL
COMMAND date +'%Y-%m-%d %H:%M:%S' > "linktimestamp.txt"
COMMAND objcopy --input binary --output elf32-i386 --binary-architecture i386 --rename-section .data=.rodata,CONTENTS,ALLOC,LOAD,READONLY,DATA "linktimestamp.txt" "linktimestamp.o"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "link timestamp: ${LINK_TIMESTAMP}"
)
endif()
#add_dependencies(${PROJECT_NAME} "linktimestamp")
target_link_libraries(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/linktimestamp.o")
Бинарная цель ${PROJECT_NAME}
, связанная каждый раз с обновленным сектором.
Qt код для получить эту метку времени:
extern char _binary_linktimestamp_txt_start[];
//extern char _binary_linktimestamp_txt_end[];
extern char _binary_linktimestamp_txt_size[];
const auto text = QByteArray::fromRawData(_binary_linktimestamp_txt_start, reinterpret_cast< std::intptr_t >(_binary_linktimestamp_txt_size));
qDebug() << QDateTime::fromString(QString::fromUtf8(text), "yyyy-MM-dd HH:mm:ss\n"));