Сомневаюсь, что такие книги существуют.
Есть
и спасибо, в хозяйстве пригодятся.
Необходимости точно не будет, поскольку все то же самое можно сделать и без них. Но так запись короче, некоторым это нравится...
Это подтверждает мои подозрения, что некоторые языки (в том числе С/С++) бедно обоснованы. В стандартах, отвечающих требованию полноты, подобные возможности рассматривать необязательно, и в книгах не приходится, т.к. "можно сделать и без них". И т.к. "некоторым это нравится", возрастают недопонимание и угроза труднообнаружимых багов. Не слишком ли увлекаются короткими записями создатели языков? Они думают, что если вместо begin/end ставить фигурные скобки, то кодер за единицу времени напишет больше кода?
Но тогда нужно быть последовательными и сокращать не только integer до int, но и while до wh
Самая ожиданная конструкция это опечатка:
До этого места все хорошо. Но проблема в том, что практически никто (в т.ч. сами разработчики из Nvidia, которые пишут программы-примеры) не заботится о том, чтобы завести эту вспомогательную переменную типа void* и приводят указатель на какой-нибудь int* (т.е. int**) к указателю на void* (т.е. void**). Но int* и void*
это два разных типа, и попытка изменить значение переменной одного типа через указатель на другой тип равносильна изменению значения типа int через указатель на double, как это делается в приведенной Вами цитате из comp.lang.c.
В CUDA значения переменных меняются обращением к ядру, там контроль за типами в порядке и нет такого, как в цитате из comp.lang.c:
int i = 1;
incme((double *)&i); /* WRONG */
Выше я приводил пример ядра:
__device__ int addem( int a, int b ) {
return a + b;
}
Полагаю, тут претензий быть не может. Что касается cudaMalloc, то она используется совместно с cudaMemcpy для клонирования пары переменных одного типа (нпр.,
с и
dev_c ). И только так. Никакой опасности такая передача параметров не содержит. Не только С/С++ используют нетипизированные переменные, но и многие другие языки. Так, Delphi во многом унаследовал строгую типизацию Pascal, но и в Delphi широко применяются механизмы, подобные cudaMalloc. Например, есть нетипизированные файлы и есть процедуры для работы с ними:
procedure blockRead(var f:file; var Buf; count: integer);
Эта процедура читает из файла f в буфер (Buf) count байт. А как будут интерпретированы эти прочитанные байты - как целые числа или как символы или как еще - решать приходится целиком программисту, и компилятор никакой ответственности за это не несет. Это единственная возможность для решения широкого круга элементарных типовых задач. В ранних стандартах Паскаля, нпр., пользовательских нетипизаций не допускалось. Хотя и там пришлось сделать исключения для библиотечных read и write. В результате на практике приходилось прибегать к трюкам:
MyType = record
case Boolean of
false: (a : type1);
true: (b: type2);
end;
Но такие трюки не помогали, когда нужно было перемножать
матрицы с заранее неизвестным
. Нетипизированные переменные - это не какое-то отступление от принципов защитного программирования, а просто другой уровень абстракции. Нпр., чтобы скопировать файл, совсем не нужно знать, какой тип у записей этого файла.