Main Content

La traducción de esta página aún no se ha actualizado a la versión más reciente. Haga clic aquí para ver la última versión en inglés.

Comprobar el código con el analizador de código para buscar errores y advertencias

El analizador de código de MATLAB® puede comprobar automáticamente el código para buscar problemas de codificación. Puede visualizar los mensajes de advertencia y error sobre el código y modificar el archivo según estos mensajes. Los mensajes se actualizan automáticamente y de forma continua para que pueda comprobar si sus cambios resuelven los problemas indicados en los mensajes. Algunos mensajes ofrecen información adicional, correcciones automáticas del código o ambas.

Activar la comprobación continua del código

Para activar la comprobación continua del código, en la pestaña Home, en la sección Environment, haga clic en Preferences. Seleccione MATLAB > Code Analyzer y, después, seleccione la casilla de verificación Enable integrated warning and error messages. Establezca la opción Underlining en Underline warnings and errors.

Cuando la comprobación continua del código está activada, MATLAB muestra mensajes de advertencia y de error sobre el código en el editor y en Live Editor. Por ejemplo, el archivo de muestra lengthofline.m contiene varios errores y advertencias. Copie el código en el editor y guarde el archivo como lengthofline.m.

 Código de lengthofline.m

Ver el estado del analizador de código para un archivo

Cuando abre un archivo en el editor o en Live Editor, el indicador de mensajes en la parte superior de la barra de indicadores muestra el estado general del analizador de código para el archivo.

Indicador de mensajesDescripción
Red error symbol

El archivo contiene errores de sintaxis u otros problemas significativos.

Yellow warning symbol

El archivo contiene advertencias u oportunidades de mejora, pero no errores.

Green check mark symbol

El archivo no contiene errores, advertencias ni oportunidades de mejora.

Por ejemplo, en lengthofline.m, el indicador de mensajes es Red error symbol, lo que significa que el archivo contiene al menos un error.

lengthofline file in the Editor with the red error symbol displayed in the indicator bar

Ver los mensajes del analizador de código

Para ir al primer fragmento de código que contiene un mensaje, haga clic en el indicador de mensajes. El fragmento de código identificado está subrayado en rojo para errores o en naranja para advertencias y oportunidades de mejora. Si el archivo contiene un error, hacer clic en el indicador de mensajes lleva al primer error.

Por ejemplo, en lengthofline.m, cuando hace clic en el indicador de mensajes, el cursor se mueve a la línea 47, donde se encuentra el primer error. MATLAB muestra los errores para esa línea junto al marcador de error en la barra de indicadores. Los mensajes múltiples pueden representar un único problema o varios problemas. Puede que resolver uno de ellos los resuelva todos. O, después de resolver uno, puede que los otros mensajes cambien o que quede más claro lo que debe hacer.

lengthofline file in the Editor after clicking the message indicator. Three errors display next to the error marker in the indicator bar.

Para ir al siguiente fragmento de código que contiene un mensaje, haga clic en el indicador de mensajes. También puede hacer clic en un marcador de la barra de indicadores para ir a la línea que representa el marcador. Por ejemplo, haga clic en el primer marcador de la barra de indicadores en lengthofline.m. El cursor se mueve al comienzo de la línea 21.

Para ver el mensaje de un fragmento de código, mueva el cursor del ratón dentro del fragmento de código subrayado. De forma alternativa, puede colocar el cursor dentro del fragmento de código subrayado y pulsar Ctrl+M. Si hay disponible información adicional para el mensaje, el mensaje incluye un botón Details. Haga clic en el botón para mostrar la información adicional y cualquier acción de usuario sugerida.

lengthofline file in the Editor showing a warning message with a details button

Resolver problemas en el código

Para cada mensaje en el archivo de código, modifique el código para resolver el problema indicado en el mensaje. A medida que modifica el código, el indicador de mensajes y el subrayado se actualizan para reflejar los cambios que hace, aunque no guarde el archivo.

Por ejemplo, en la línea 47 en lengthofline.m, el mensaje sugiere un desequilibrio de delimitador. Cuando mueve las teclas de flecha por encima de cada delimitador, MATLAB no parece indicar un desajuste. No obstante, el análisis de código detecta el punto y coma en data{3}(;) y lo interpreta como el final de una instrucción.

lengthofline file in the Editor after clicking the message indicator. Three errors display next to the error marker in the indicator bar.

Para resolver el problema en la línea 47, cambie data{3}(;) a data{3}(:). Este cambio único resuelve todos los mensajes en la línea 47 y ya no aparece el subrayado para la línea. Dado que el cambio elimina el único error en el archivo, el indicador de mensajes en la parte superior de la barra cambia de Red error symbol a Yellow warning symbol, lo que indica que solo quedan advertencias y posibles mejoras.

Para algunos mensajes, MATLAB sugiere una corrección automática que puede aplicar para resolver el problema. Si hay una corrección automática disponible para un problema, el fragmento de código se resalta y el mensaje incluye un botón Fix.

lengthofline file in the Editor showing a warning message with a fix button

Por ejemplo, en la línea 27 en lengthofline.m, coloque el ratón encima del fragmento de código subrayado y resaltado prod. El mensaje mostrado incluye un botón Fix.

Si sabe cómo resolver el problema, quizá por tener experiencia previa, haga clic en el botón Fix o pulse Alt+Enter. Si no conoce el problema, haga clic con el botón secundario en el código resaltado. El primer elemento en el menú contextual muestra la corrección sugerida. Seleccione el elemento para aplicar la corrección.

lengthofline file in the Editor showing the context menu. The first item in the menu is the suggested fix.

Si existen varias instancias de un problema, MATLAB podría ofrecer aplicar la corrección sugerida para todas las instancias del problema. Para aplicar la corrección a todas las instancias de un problema, haga clic con el botón secundario en el código resaltado y seleccione Fix All (n) Instances of This Issue. Esta opción no está disponible para todas las correcciones sugeridas.

Después de modificar el código para resolver todos los mensajes o desactivar los mensajes designados, el indicador de mensajes cambia a verde. Vea el archivo de ejemplo, lengthofline2.m, con todos los mensajes resueltos.

 Código de lengthofline2.m

Analizar archivos con la app del analizador de código

Desde R2022b

Puede crear un informe de los mensajes del analizador de código para todos los archivos de una carpeta con la app Code Analyzer.

Para abrir la app:

  • Barra de herramientas de MATLAB: en la pestaña Apps, en MATLAB, haga clic en el icono de la app: Code Analyzer App Icon.

  • Línea de comandos de MATLAB: introduzca codeAnalyzer.

Code Analyzer app showing an overall summary of code issues and code health details

Identificar y almacenar problemas en archivos con un objeto codeIssues

Desde R2022b

Puede utilizar codeIssues para encontrar y almacenar problemas en código de forma programática. El objeto codeIssues almacena problemas encontrados por el analizador de código de MATLAB. Los problemas encontrados en uno o más archivos o carpetas especificados pueden clasificarse y filtrarse, bien de forma programática en la línea de comandos, bien de manera interactiva en la app del analizador de código.

Por ejemplo, puede generar un objeto codeIssues que contenga los problemas en un archivo especificado:

issues = codeIssues("test.m")
issues = 

  codeIssues with properties:

                         Date: 18-Oct-2022 14:18:54
                      Release: "R2023a"
                        Files: "C:\MyCode\test.m"
    CodeAnalyzerConfiguration: "active"
                       Issues: [3×10 table]
             SuppressedIssues: [0×11 table]


    Issues table preview

    Location    Severity    Fixability                                            Description                                             CheckID    LineStart    LineEnd    ColumnStart    ColumnEnd       FullFilename   
    ________    ________    __________    ____________________________________________________________________________________________    _______    _________    _______    ___________    _________    __________________

    "test.m"      info        manual      "Variable appears to change size on every loop iteration. Consider preallocating for speed."    AGROW          3           3            1             3        "C:\MyCode\test.m"
    "test.m"      info        auto        "Add a semicolon after the statement to hide the output (in a script)."                         NOPTS          6           6            3             3        "C:\MyCode\test.m"
    "test.m"      info        auto        "string('...') is not recommended. Use "..." instead."                                          STRQUOT        8           8            1            13        "C:\MyCode\test.m"

Analizar archivos con la herramienta de problemas de código de MATLAB Online

En MATLAB Online™, puede utilizar la herramienta de problemas de código para ver los mensajes de error y advertencia sobre el código. La herramienta de problemas de código muestra los problemas de código encontrados por el analizador de código de MATLAB cuando comprueba automáticamente el código.

Para abrir la herramienta de problemas de código, vaya a la pestaña Editor o Live Editor y, en la sección Analyze, haga clic en Code Issues. De forma predeterminada, la herramienta de problemas de código se abre a la derecha del escritorio. Para ocultar la herramienta de problemas de código, haga clic en el icono de problemas de código en la barra lateral.

Code Issues tool showing 0 errors and 13 warnings found in the lengthofline.m file. The MATLAB Online desktop right sidebar shows the Code Issues icon.

Puede cambiar los mensajes que se muestran en la herramienta de problemas de código con las opciones de la parte superior de la herramienta:

  • Mostrar mensajes para el archivo actual o para todos los archivos abiertos: utilice la lista desplegable en la parte superior izquierda de la herramienta de problemas de código para seleccionar si desea mostrar los errores y advertencias del archivo actual o de todos los archivos abiertos. Por ejemplo, para mostrar los errores y advertencias de todos los archivos abiertos, en la lista desplegable, seleccione Open Files.

  • Mostrar u ocultar errores y advertencias: utilice el botón de errores y el botón de advertencias en la parte superior derecha de la herramienta de problemas de código para mostrar u ocultar los errores y advertencias. Por ejemplo, para mostrar solo errores, habilite el botón de errores y desactive el botón de advertencias .

  • Filtrar mensajes por texto: utilice el campo de búsqueda que se encuentra debajo de la lista desplegable para filtrar la lista de mensajes por texto. Por ejemplo, para mostrar solo mensajes que contengan la palabra Variable, introduzca la palabra Variable en el campo de búsqueda.

Ajustar los indicadores de mensajes y los mensajes del analizador de código

Puede especificar qué tipo de problemas de código se subrayan para que se adapten mejor a la fase de desarrollo actual. Por ejemplo, cuando comienza a codificar, podría preferir que se subrayen únicamente los errores, ya que las advertencias pueden distraer. Para cambiar las preferencias de subrayado, en la pestaña Home, en la sección Environment, haga clic en Preferences. Seleccione MATLAB > Code Analyzer y, después, seleccione una opción Underlining.

También puede ajustar qué mensajes ve cuando analiza el código. El análisis de código no proporciona información perfecta sobre todas las situaciones. En ocasiones, puede que no desee cambiar el código de acuerdo con las indicaciones de un mensaje. Si no desea cambiar el código y no desea ver el indicador y el mensaje para una línea específica, puede suprimirlos. Por ejemplo, el primer mensaje de la línea 48 del archivo de muestra lengthofline.m es Terminate statement with semicolon to suppress output (in functions). Añadir un punto y coma al final de una instrucción suprime la salida y es una práctica habitual. El análisis de código avisa sobre líneas que producen salidas, pero no cuentan con el punto y coma de finalización. Si desea ver la salida de la línea 48, no añada el punto y coma como sugiere el mensaje.

Puede suprimir (desactivar) los indicadores para mensajes de advertencia y error de estas formas:

  • Suprimiendo una instancia de un mensaje en el archivo actual.

  • Suprimiendo todas las instancias de un mensaje en el archivo actual.

  • Suprimiendo todas las instancias de un mensaje en todos los archivos.

No puede suprimir mensajes de error tales como errores de sintaxis.

Suprimir una instancia de un mensaje en el archivo actual

Puede suprimir una instancia específica de un mensaje del analizador de código en el archivo actual. Por ejemplo, para suprimir el mensaje en la línea 48 del archivo de muestra lengthofline.m, haga clic con el botón secundario en el primer subrayado en la línea 48 y seleccione Suppress 'Terminate statement with semicolon...' > On This Line.

El comentario %#ok<NOPRT> aparece al final de la línea e indica a MATLAB que suprima el mensaje Terminate statement with semicolon to suppress output (in functions) del analizador de código para esa línea. Desaparecen el subrayado y la marca en la barra de indicadores para el mensaje.

Si una línea contiene dos mensajes que no desea que se muestren, haga clic con el botón secundario en cada subrayado por separado y seleccione la entrada apropiada del menú contextual. La sintaxis %#ok se expande. Por ejemplo, suprimir ambos mensajes para la línea 48 en el archivo de muestra lengthofline.m añade el comentario %#ok<NBRAK,NOPRT> al final de la línea.

Aunque las preferencias del analizador de código estén configuradas para activar este mensaje, la instancia específica del mensaje suprimido no aparece porque %#ok tiene precedencia frente a la configuración de preferencias. Si posteriormente decide que desea mostrar el mensaje Terminate statement with semicolon to suppress output (in functions) del analizador de código para esa línea, elimine %#ok<NOPRT> de la línea.

Suprimir todas las instancias de un mensaje en el archivo actual

Puede suprimir todas las instancias de un mensaje específico del analizador de código en el archivo actual. Por ejemplo, para suprimir todas las instancias del mensaje en la línea 48 del archivo de muestra lengthofline.m, haga clic con el botón secundario en la línea 48 y seleccione Suppress 'Terminate statement with semicolon...' > In This File.

El comentario %#ok<*NOPRT> aparece al final de la línea e indica a MATLAB que suprima todas las instancias del mensaje Terminate statement with semicolon to suppress output (in functions) del analizador de código en el archivo actual. Todos los subrayados y las marcas en la barra de indicadores de mensaje que corresponden a este mensaje desaparecen.

Si una línea contiene dos mensajes que no desea que se muestren en ninguna parte del archivo actual, haga clic con el botón secundario en cada subrayado por separado y seleccione la entrada apropiada del menú contextual. La sintaxis %#ok se expande. Para el ejemplo, suprimir ambos mensajes para la línea 48 en el archivo de muestra lengthofline.m añade el comentario %#ok<*NBRAK,*NOPRT>.

Aunque las preferencias del analizador de código estén configuradas para activar este mensaje, el mensaje no aparece porque %#ok tiene precedencia frente a la configuración de preferencias. Si posteriormente decide que desea mostrar todas las instancias del mensaje Terminate statement with semicolon to suppress output (in functions) del analizador de código en el archivo actual, elimine %#ok<*NOPRT> de la línea.

Suprimir todas las instancias de un mensaje en todos los archivos

Puede desactivar todas las instancias de un mensaje del analizador de código en todos los archivos. Por ejemplo, para suprimir todas las instancias en todos los archivos del mensaje en la línea 48 del archivo de muestra lengthofline.m, haga clic con el botón secundario en la línea 48 y seleccione Suppress 'Terminate statement with semicolon...' > In All Files. Esta opción modifica las preferencias del analizador de código.

Si sabe qué mensajes desea suprimir, puede desactivarlos directamente con las preferencias del analizador de código:

  1. En la pestaña Home, en la sección Environment, haga clic en Preferences.

  2. Seleccione MATLAB > Code Analyzer.

  3. Busque entre los mensajes para encontrar los que desea suprimir.

  4. Desactive la casilla de verificación asociada a cada mensaje que desea suprimir en todos los archivos.

  5. Haga clic en OK.

Guardar y reutilizar la configuración de mensajes del analizador de código

Puede establecer opciones para activar o desactivar determinados mensajes del analizador de código y, después, guardar esa configuración en un archivo. Cuando desee utilizar un archivo de configuración con un archivo en particular, selecciónelo en las preferencias del analizador de código. El archivo de configuración sigue vigente hasta que selecciona otro archivo de configuración. Habitualmente, se cambia el archivo de configuración cuando tiene un subconjunto de archivos para el que desea utilizar un archivo de configuración en particular.

Para guardar la configuración en un archivo:

  1. En la pestaña Home, en la sección Environment, haga clic en Preferences.

  2. Seleccione MATLAB > Code Analyzer.

  3. Active o desactive mensajes o categorías de mensajes específicos.

  4. Haga clic en el botón Actions , seleccione Save As y, después, guarde la configuración en un archivo txt.

  5. Haga clic en OK.

Puede reutilizar esta configuración para cualquier archivo de MATLAB o puede proporcionar el archivo de configuración a otro usuario. Para utilizar la configuración guardada:

  1. En la pestaña Home, en la sección Environment, haga clic en Preferences.

  2. Seleccione MATLAB > Code Analyzer.

  3. Abra la lista Active settings y seleccione Browse.

  4. Elija cualquiera de los archivos de configuración.

    La configuración que elija seguirá en vigor para todos los archivos de MATLAB hasta que seleccione otro conjunto de configuración del analizador de código.

Activar las comprobaciones personalizadas y configurar las comprobaciones existentes

Desde R2023a

Puede configurar las comprobaciones existentes mostradas por el analizador de código en el editor de MATLAB y añadir comprobaciones personalizadas colocando un archivo llamado codeAnalyzerConfiguration.json en una carpeta de recursos. El archivo de configuración es efectivo en la carpeta que contiene la carpeta de recursos y en cualquier subcarpeta.

Puede modificar las comprobaciones existentes del analizador de código, incluyendo si la comprobación está activada o no y su gravedad, el texto de los mensajes y los parámetros, si la comprobación los tiene, para limitar el número de argumentos de entrada y salida para una función. También puede crear comprobaciones personalizadas que se activen cuando utiliza funciones específicas. Para obtener más información sobre cómo configurar las comprobaciones del analizador de código, consulte Configure Code Analyzer.

Valide el archivo de configuración codeAnalyzerConfiguration.json para que tenga el formato adecuado con la función matlab.codeanalysis.validateConfiguration.

Comprender código que contiene mensajes suprimidos

Si recibe código que contiene mensajes suprimidos, puede que desee revisar los mensajes sin necesidad de desactivar primero su supresión. Un mensaje podría estar en un estado suprimido por cualquiera de las siguientes razones:

  • Una o más directivas %#ok<message-ID> están en una línea de código que genera un mensaje especificado por <message-ID>.

  • Una o más directivas %#ok<*message-ID> están en un archivo que genera un mensaje especificado por <message-ID>.

  • Los mensajes están borrados en el panel de preferencias del analizador de código.

  • Los mensajes están desactivados de forma predeterminada.

Para determinar por qué los mensajes están suprimidos, llame a codeIssues con el archivo como entrada.

issues = codeIssues("myFile.m")

La salida, issues, tendrá una propiedad, SuppressedIssues, que contiene la tabla con todos los problemas suprimidos dentro del archivo. Revise el mensaje asociado a cada problema para comprender porque está suprimido.

Comprender las limitaciones del análisis de código

El análisis de código es una herramienta valiosa, pero tiene algunas limitaciones:

  • En ocasiones, el análisis de código no genera mensajes del analizador de código donde se esperan.

    Por su diseño, el análisis de código intenta minimizar el número de mensajes incorrectos que devuelve, aunque este comportamiento permita que algunos problemas no se detecten.

  • En ocasiones, el análisis de código genera mensajes que no se aplican a su situación.

    Hacer clic en el botón Details para mostrar información adicional para un mensaje puede ayudar a determinar si el mensaje se aplica a su situación. Los mensajes de error son casi siempre problemas. No obstante, muchas advertencias son sugerencias para revisar algo en el código que es inusual, pero que podría ser correcto en su caso.

    Suprima un mensaje de advertencia si tiene la certeza de que el mensaje no se aplica a su situación. Si la razón para suprimir un mensaje es sutil o poco clara, incluya un comentario con la explicación. De este modo, quienes lean el código estarán al tanto de la situación.

    Para obtener más información, consulte Ajustar los indicadores de mensajes y los mensajes del analizador de código.

Distinguir los nombres de funciones de los nombres de variables

El análisis de código no siempre puede distinguir los nombres de funciones de los nombres de variables. Para el siguiente código, si el mensaje del analizador de código se activa, el análisis de código devuelve el mensaje Code Analyzer cannot determine whether xyz is a variable or a function, and assumes it is a function. El análisis de código no puede realizar una determinación porque xyz no tiene ningún valor evidente asignado. No obstante, puede que el código haya ubicado el valor en el área de trabajo de una forma que el análisis de código no pueda detectar.

function y=foo(x)
   .
   .
   .
   y = xyz(x);
end

Por ejemplo, en el siguiente código, xyz puede ser una función o una variable cargada desde el archivo MAT. El análisis de código no tiene forma de realizar una determinación.

function y=foo(x)
    load abc.mat
    y = xyz(x);
end
También puede que las variables no sean detectadas por el análisis de código cuando use las funciones eval, evalc, evalin o assignin.

Si el análisis de código confunde una variable con una función, realice una de las siguientes acciones:

  • Inicialice la variable para que el análisis de código no la trate como a una función.

  • Para la función load, especifique el nombre de la variable explícitamente en la línea de comandos load. Por ejemplo:

     function y=foo(x)
         load abc.mat xyz
         y = xyz(x);
     end

Distinguir entre estructuras y objetos de identificadores

El análisis de código no siempre puede distinguir entre estructuras y objetos de identificadores. En el siguiente código, si x es una estructura, podría esperar un mensaje del analizador de código indicando que el código nunca utiliza el valor actualizado de la estructura. No obstante, si x es un objeto de identificador, este código puede ser correcto.

function foo(x)
		x.a = 3;
end

El análisis de código no puede determinar si x es una estructura o un objeto de identificador. Para minimizar el número de mensajes incorrectos, el análisis de código no devuelve mensajes para el código anterior, aunque podría contener un bug sutil y grave.

Distinguir las funciones integradas de las funciones sobrecargadas

Si algunas funciones integradas están sobrecargadas en una clase o en la ruta, los mensajes del analizador de código podrían aplicarse a la función integrada, pero no a la función sobrecargada a la que está llamando. En este caso, suprima el mensaje en la línea donde aparece o suprímalo para todo el archivo.

Para obtener información sobre cómo suprimir mensajes, consulte Ajustar los indicadores de mensajes y los mensajes del analizador de código.

Determinar el tamaño o la forma de las variables

El análisis de código tiene una capacidad limitada de determinar el tipo de variables y la forma de las matrices. El análisis de código podría generar mensajes apropiados para el caso más común, como para vectores. Sin embargo, estos mensajes podrían no ser apropiados para casos menos comunes, como para matrices.

Analizar definiciones de clases con superclases

El analizador de código tiene una capacidad limitada para comprobar las definiciones de clases con superclases. Por ejemplo, el analizador de código no siempre puede determinar si la clase es una clase de identificadores, pero, a veces, puede validar los atributos personalizados utilizados en una clase si los atributos se heredan de una superclase. Cuando analiza definiciones de clases, el analizador de código intenta utilizar información de las superclases, pero, a menudo, no puede obtener información suficiente para realizar una determinación en particular.

Analizar métodos de clase

La mayoría de los métodos de clase deben contener al menos un argumento que sea un objeto de la misma clase que el método. Pero este argumento no tiene que ser siempre el primer argumento. Cuando lo es, el análisis de código puede determinar que un argumento es un objeto de la clase que usted está definiendo y puede realizar varias comprobaciones. Por ejemplo, el análisis de código puede comprobar que los nombres de propiedad y método existen y que están escritos correctamente. Sin embargo, cuando el análisis de código no puede determinar que un objeto es un argumento de la clase que está definiendo, no puede realizar estas comprobaciones.

Activar los mensajes del despliegue de MATLAB Compiler

Puede cambiar entre mostrar y ocultar los mensajes del despliegue de MATLAB Compiler cuando trabaja en un archivo cambiando la preferencia del analizador de código para esta categoría de mensajes. Su elección podría depender de si está trabajando en un archivo que desea desplegar. Cambiar esta preferencia también cambia la configuración en el editor. De forma similar, cambiar la configuración en el editor cambia esta preferencia. No obstante, si las preferencias del analizador de código están abiertas cuando modifica la configuración en el editor, los cambios no se reflejan en la ventana de preferencias. Tanto si cambia la configuración en el editor como si la cambia en la ventana de preferencias, el cambio se aplica al editor y al informe del analizador de código.

Para activar los mensajes de despliegue de MATLAB Compiler™:

  1. En la pestaña Home, en la sección Environment, haga clic en Preferences.

  2. Seleccione MATLAB > Code Analyzer.

  3. Haga clic en la flecha hacia abajo situada junto al campo de búsqueda y, después, seleccione Show Messages in Category > MATLAB Compiler (Deployment) Messages.

  4. Haga clic en el botón Enable Category a la derecha del título de categoría MATLAB Compiler (Deployment) Messages.

  5. Borre los mensajes individuales que no desee mostrar para su código.

  6. Decida si desea guardar esta configuración para reutilizarla la próxima vez que trabaje en un archivo que se va a desplegar.

El archivo de configuración txt, que puede crear como se describe en Guardar y reutilizar la configuración de mensajes del analizador de código, incluye el estado de esta configuración.

Consulte también

| |

Temas relacionados

Sitios web externos