Оказывается, проблема была не в компиляции статической библиотеки, а в компоновке указанной библиотеки.
Проблема была исправлена для меня путем изменения:
# Link executable
$(EXEC): $(OBJS)
$(CC) $^ -o $(OUTDIR)$@ $(LDFLAGS) $(LIB)
На:
# Link executable
$(EXEC): $(OBJS)
$(CC) $^ -o $(OUTDIR)$@ $(LIB) $(LDFLAGS)
Так, что статическая библиотека, которая является просто набором объектов, связана с другие объекты, прежде чем ссылаться на библиотеки CUDA в $ (LDFLAGS).
Примечание также для всех, кто споткнется об этом в будущем; похоже, это немного зависит от версии вашего компилятора, независимо от того, вызывает ли это ошибку на самом деле.
Мне нравится использовать: ArgumentException
, ArgumentNullException
и ArgumentOutOfRangeException
.
ArgumentException
- что-то есть неправильно с аргументом. ArgumentNullException
- Аргумент нулевой. ArgumentOutOfRangeException
- Я не часто его использую, но обычно используется индексация в коллекции и предоставление индекса, который к большому. Существуют и другие опции, которые не столько фокусируются на самом аргументе, сколько оценивают вызов в целом:
InvalidOperationException
- Аргумент может быть в порядке, но не в текущее состояние объекта. Кредит переходит в STW (ранее Yoooder). Проголосуйте и за его ответ . NotSupportedException
- Переданные аргументы действительны, но просто не поддерживается в этой реализации. Представьте себе FTP-клиента, и вы передаете команду, которую клиент не поддерживает. Хитрость заключается в том, чтобы создать исключение, которое лучше всего выражает, почему метод нельзя назвать таким, какой он есть. В идеале, исключение должно быть детализированным о том, что пошло не так, почему это неправильно и как это исправить.
Мне нравится, когда сообщения об ошибках указывают на помощь, документацию или другие ресурсы. Например, Microsoft сделала хороший первый шаг со своими статьями базы знаний, например, «Почему я получаю сообщение об ошибке« Операция прервана »при посещении веб-страницы в Internet Explorer?» . Когда вы сталкиваетесь с ошибкой, они указывают на статью базы знаний в сообщении об ошибке. Что они не делают хорошо, так это то, что они не говорят вам, почему конкретно это не удалось.
Спасибо еще раз STW (бывший Yoooder) за комментарии.
В ответ на ваше продолжение я бы сгенерировал ArgumentOutOfRangeException
. Посмотрите, что MSDN говорит об этом исключении: выброшено
ArgumentOutOfRangeException
когда метод вызывается и по крайней мере один из аргументов, переданных метод не является нулевым ссылка (Ничего
в Visual Basic) и не содержит действительного значения.
Таким образом, в этом случае вы передаете значение, но это не является допустимым значением, поскольку ваш диапазон составляет 1–12. Однако то, как вы документируете, проясняет, что выдает ваш API. Потому что хотя я мог бы сказать ArgumentOutOfRangeException
, другой разработчик может сказать ArgumentException
. Упростите и запишите поведение.
Я проголосовал за ответ Джоша , но хотел бы добавить еще один в список:
System.InvalidOperationException должно быть выброшено, если аргумент допустим, но объект находится в состоянии, в котором аргумент не должен использоваться.
Update Взято из MSDN:
InvalidOperationException используется в случаи, когда неспособность вызвать Метод вызван причинами, отличными от неверные аргументы.
Допустим, у вашего объекта есть метод PerformAction (действие enmSomeAction), допустимыми являются enmSomeActions Open и Close. Если вы вызываете PerformAction (enmSomeAction.Open) два раза подряд, то второй вызов должен вызвать исключение InvalidOperationException (поскольку arugment был действителен, но не для текущего состояния элемента управления)
, поскольку вы уже делаете правильные вещи при программировании для защиты я должен упомянуть еще одно исключение - ObjectDisposedException. Если ваш объект реализует IDisposable, тогда у вас всегда должна быть переменная класса, отслеживающая состояние удаления; если ваш объект был удален и для него вызван метод, вы должны вызвать исключение ObjectDisposedException:
public void SomeMethod()
{
If (m_Disposed) {
throw new ObjectDisposedException("Object has been disposed")
}
// ... Normal execution code
}
Обновление: Чтобы ответить на ваши последующие действия: Это немного двусмысленная ситуация, и усложняется общим (не в смысле .NET Generics) типом данных, используемым для представления определенного набора данных; перечисление или другой строго типизированный объект были бы более идеальным соответствием - но у нас не всегда есть этот элемент управления.
Я лично склонялся бы к ArgumentOutOfRangeException и предоставил бы сообщение, которое указывает, что допустимые значения 1-12. Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода.
NET Generics смысле) тип данных, используемый для представления определенного набора данных; перечисление или другой строго типизированный объект были бы более идеальным соответствием - но у нас не всегда есть этот элемент управления.Я лично склонялся бы к ArgumentOutOfRangeException и предоставил бы сообщение, которое указывает, что допустимые значения 1-12. Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода.
NET Generics смысле) тип данных, используемый для представления определенного набора данных; перечисление или другой строго типизированный объект были бы более идеальным соответствием - но у нас не всегда есть этот элемент управления.Я лично склонялся бы к ArgumentOutOfRangeException и предоставил бы сообщение, которое указывает, что допустимые значения 1-12. Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода.
перечисление или другой строго типизированный объект были бы более идеальным соответствием - но у нас не всегда есть этот элемент управления.Я лично склонялся бы к ArgumentOutOfRangeException и предоставил бы сообщение, которое указывает, что допустимые значения 1-12. Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода.
перечисление или другой строго типизированный объект были бы более идеальным соответствием - но у нас не всегда есть этот элемент управления.Я лично склонялся бы к ArgumentOutOfRangeException и предоставил бы сообщение, которое указывает, что допустимые значения 1-12. Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода.
Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода. Я рассуждаю так: когда вы говорите о месяцах, предполагая, что все целочисленные представления месяцев действительны, то вы ожидаете значение в диапазоне 1-12. Если бы действовали только определенные месяцы (например, месяцы, в которых было 31 день), вы бы не имели дело с самим диапазоном, и я бы выдал обобщенное исключение ArgumentException, в котором указаны действительные значения, и я также задокументировал бы их в комментариях метода.В зависимости от фактического значения и какое исключение подходит лучше всего:
ArgumentException
(что-то не так со значением)
ArgumentNullException
(аргумент нулевой, хотя это недопустимо)
ArgumentOutOfRangeException
(аргумент имеет значение за пределами допустимого диапазона)
Если это не достаточно точно, просто выведите свой собственный класс исключений из ArgumentException
.
Ответ Yoooder меня просветил. Вход является недопустимым , если он недействителен в любое время, тогда как вход является неожиданным , если он недопустим для текущего состояния системы.
ArgumentException выдается, когда метод вызывается и по крайней мере один из переданные аргументы не соответствуют спецификация параметров вызываемого метод. Все случаи ArgumentException должен иметь осмысленное сообщение об ошибке, описывающее неверный аргумент, а также ожидаемый диапазон значений для Аргумент.
Несколько подклассов также существуют для определенных типов инвалидности. Ссылка содержит резюме подтипов и когда они должны применяться.
Краткий ответ:
Ни
Более длинный ответ:
с использованием аргумента * Exception (за исключением библиотеки, которая является Продукт на его, например, компонент библиотеки) является запахом. Исключения предназначены для обработки исключительных ситуаций, а не ошибок и не недостатков пользователя (т. Е. Пользователя API).
Самый длинный ответ:
Бросать исключения для недопустимых аргументов - это грубо, если только вы не пишете библиотеку.
Я предпочитаю использовать утверждения по двум (или более) причинам:
Вот как выглядит обработка пустых исключений (с сарказмом, очевидно):
try {
library.Method(null);
}
catch (ArgumentNullException e) {
// retry with real argument this time
library.Method(realArgument);
}
Исключения следует использовать, когда ситуация ожидаемая, но исключительная (случаются вещи, которые находятся вне контроля потребителя, такие как сбой ввода-вывода). Аргумент * Исключение является признаком ошибки и должно (на мой взгляд) обрабатываться с помощью тестов и помогать с Debug.Assert
Кстати: в этом конкретном случае вы могли бы использовать тип Month вместо int. C # терпит неудачу, когда дело доходит до безопасности типов (Aspect # rulez!), Но иногда вы можете предотвратить (или отловить во время компиляции) эти ошибки все вместе.
И да, MicroSoft ошибается в этом.
Существует стандартное ArgumentException, которое вы можете использовать, или вы можете создать подкласс и создать свой собственный. Существует несколько определенных классов ArgumentException:
http://msdn.microsoft.com/en-us/library/system.argumentexception (VS.71) .aspx
Какой из них работает лучше всего